问题
I have a Window with two tabs, that holds two different user controls. In order to enable/disable navigation to the second tab, I implement an IsEnabled
property in both VM's from the IPageViewModel
interface.
The IsEnabled boolean property is set to true when a SelectedCustomer
is received in the CustomerOrdersViewModel
, via Messenger service from CustomerDetailsViewModel
.
So far this method works, as the second tab is enabled when I select a customer from the data grid in the first view. But the problem is when I try to select the first tab to go back to the initial view, it is disabled.
This is a screen cast of the specific navigation issue.
I'm not sure why as I thought when I set the IsEnabled property to true using the messenger, both tabs would be enabled.
Does anyone have any advice on the issue here?
In the CustomerDetailsViewModel
I send the selectedCustomer via a messenger:
private CustomerModel selectedCustomer;
public CustomerModel SelectedCustomer
{
get
{
return selectedCustomer;
}
set
{
selectedCustomer = value;
Messenger.Default.Send<CustomerModel>(selectedCustomer);
RaisePropertyChanged("SelectedCustomer");
}
}
Then in the CustomerDetailsViewModel
the IsEnabled property is set to true as the SelectedCustomer has been passed over:
public CustomerOrdersViewModel()
{
Messenger.Default.Register<CustomerModel>(this, OnCustomerReceived);
}
public void OnCustomerReceived(CustomerModel customer)
{
SelectedCustomer = customer;
IsEnabled = true;
}
This is the ApplicationView xaml that holds both user controls, and the tabs generated for each:
<Window x:Class="MongoDBApp.Views.ApplicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:MongoDBApp.Views"
xmlns:vm="clr-namespace:MongoDBApp.ViewModels"
Title="ApplicationView"
Width="800"
Height="500">
<Window.Resources>
<DataTemplate DataType="{x:Type vm:CustomerDetailsViewModel}">
<views:CustomerDetailsView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CustomerOrdersViewModel}">
<views:CustomerOrdersView />
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<vm:ApplicationViewModel />
</Window.DataContext>
<TabControl ItemsSource="{Binding PageViewModels}"
SelectedItem="{Binding CurrentPageViewModel}"
TabStripPlacement="Top">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Window>
回答1:
Why not just default the IsEnabled
property of the CustomerDetailsViewModel
to true?
It's a tab that should always be enabled, so that would make the most sense to me.
回答2:
I presume you assign new ViewModel, either CustomerDetails or CustomerOrders, to CurrentPageViewModel. Whenever you do so a new object of class is created with IsEnabled set to false by default.
The work around is to create IsEnabled property in ViewModel associated with your View (ApplicationViewModel). Then in ItemContrainerStyle refer to it as follows:
<Setter Property="IsEnabled" Value="{Binding RelativeSource={RelativeSource AncestoryType=Window}, Path=DataContext.IsEnabled}"/>
Neither IsEnabled nor Messages are required in TabControlPages' ViewModels since your IsEnabled property resides in main ViewModel and both TabPages refer to it.
EDIT
After a while I realized that it would be disable by default since IsDefault would equal false at very beginning. It is complicated because you do not explicitly create TabPage. I am attaching complete solution for this, take a look
here.
来源:https://stackoverflow.com/questions/34042541/how-to-handle-enabled-property-of-multiple-tabs-using-data-templates