Как обработать включенное свойство нескольких вкладок с помощью шаблонов данных?
У меня есть окно с двумя вкладками, которое содержит два разных пользовательских элемента управления. Чтобы включить / отключить навигацию ко второй вкладке, я реализую IsEnabled
собственность в обеих ВМ из IPageViewModel
интерфейс.
Для логического свойства IsEnabled устанавливается значение true, если SelectedCustomer
получен в CustomerOrdersViewModel
через службу Messenger от CustomerDetailsViewModel
,
Пока этот метод работает, так как вторая вкладка включена, когда я выбираю клиента из сетки данных в первом представлении. Но проблема в том, что когда я пытаюсь выбрать первую вкладку, чтобы вернуться к исходному виду, она отключается.
Это скриншот конкретной проблемы навигации.
Я не уверен, почему, как я думал, когда я установил для свойства IsEnabled значение true с помощью мессенджера, обе вкладки будут включены.
Кто-нибудь есть какие-либо советы по этому вопросу здесь?
в CustomerDetailsViewModel
Я отправляю выбранного клиента через мессенджер:
private CustomerModel selectedCustomer;
public CustomerModel SelectedCustomer
{
get
{
return selectedCustomer;
}
set
{
selectedCustomer = value;
Messenger.Default.Send<CustomerModel>(selectedCustomer);
RaisePropertyChanged("SelectedCustomer");
}
}
Тогда в CustomerDetailsViewModel
свойство IsEnabled имеет значение true, так как SelectedCustomer был передан:
public CustomerOrdersViewModel()
{
Messenger.Default.Register<CustomerModel>(this, OnCustomerReceived);
}
public void OnCustomerReceived(CustomerModel customer)
{
SelectedCustomer = customer;
IsEnabled = true;
}
Это xaml ApplicationView, который содержит как пользовательские элементы управления, так и вкладки, сгенерированные для каждого:
<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>
2 ответа
Почему бы просто не по умолчанию IsEnabled
собственность CustomerDetailsViewModel
к правде?
Это вкладка, которая всегда должна быть включена, чтобы она имела для меня смысл.
Я предполагаю, что вы назначаете новую ViewModel, CustomerDetails или CustomerOrders, для CurrentPageViewModel. Всякий раз, когда вы делаете это, новый объект класса создается с IsEnabled, установленным в false по умолчанию.
Обходной путь - создать свойство IsEnabled в ViewModel, связанное с вашим представлением (ApplicationViewModel). Затем в ItemContrainerStyle обращайтесь к нему следующим образом:
<Setter Property="IsEnabled" Value="{Binding RelativeSource={RelativeSource AncestoryType=Window}, Path=DataContext.IsEnabled}"/>
Ни IsEnabled, ни сообщения не требуются в ViewModels TabControlPages, так как ваше свойство IsEnabled находится в основной ViewModel, и обе TabPages ссылаются на него.
РЕДАКТИРОВАТЬ
Через некоторое время я понял, что по умолчанию он будет отключен, поскольку IsDefault в самом начале будет равен false. Это сложно, потому что вы явно не создаете TabPage. Я прилагаю полное решение для этого, посмотрите здесь.