Как изменить вкладку из TabControl в WPF без нарушения шаблона MVVM
мои окна WPF содержат TabControl, который отображает содержимое на разных вкладках. Щелчок по кнопке ниже выполняет метод через интерфейс / привязку ICommand. Вызываемый метод генерирует текст, который предназначен для отображения во второй вкладке.
Как я могу переключиться на вторую вкладку при нажатии кнопки, не нарушая шаблон MVVM?
Я попытался связать TabItem.IsSelected свойство к чему-то в моей ViewModel, но я хотел используйте также другие вкладки (tab1).
какие мысли?
5 ответов
я выяснил это сам.
ключ является двусторонней привязкой. При нажатии на кнопку устанавливается свойство DisplayXamlTab
true. The IsSelected
атрибут привязан к этой переменной. если щелкнуть другую вкладку, привязка установит для свойства DisplayXamlTab значение false.
Примечание: UpdateSourceTrigger=PropertyChanged
очень важно
код ниже:
XAML:
<TabItem Header="XAML" IsSelected="{Binding DisplayXamlTab, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<Grid Background="#FFE5E5E5">
<TextBox x:Name="TxtXamlOutput" IsReadOnly="True" Text="{Binding XamlText, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible"/>
</Grid>
</TabItem>
Свойство C#:
private bool displayXamlTab;
public bool DisplayXamlTab
{
get { return this.displayXamlTab; }
set
{
this.displayXamlTab = value;
this.RaisePropertyChanged("DisplayXamlTab");
}
}
Если вы идете в MVVM, как вы собираетесь создать два свойства зависимостей в коде:
ObservableCollection<ItemType> Items;
ItemType MySelectedItem;
затем привяжите свойство TabControl ItemsSource к предметы и привязать свойство SelectedItem к MySelectedItem
<TabControl ItemsSource="{Binding Items}"
SelectedItem="{Binding MySelectedItem, Mode=TwoWay}">
<TabControl.ItemTemplate>
<DataTemplate>
<... here goes the UI to display ItemType ... >
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
Если вы хотите изменить выбранную вкладку, просто обновите свойство MySelectedItem dependecy
хотя этот вопрос довольно старый и уже хорошо ответил, я подумал, что добавлю этот дополнительный ответ, чтобы продемонстрировать альтернативный способ изменения выбранного TabItem
на TabControl
. Если у вас есть модель представления для каждого TabItem
, тогда может быть полезно иметь IsSelected
свойство в нем, чтобы определить, выбран ли он или нет. Можно данные привязать это IsSelected
собственность с TabItem.IsSelected
свойство с помощью ItemContainerStyle
свойства:
<TabControl ItemsSource="{Binding MenuItems}" TabStripPlacement="Top">
<TabControl.ItemTemplate>
<DataTemplate DataType="{x:Type ControlViewModels:MenuItemViewModel}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImageSource}" Margin="0,0,10,0" />
<TextBlock Text="{Binding HeaderText}" FontSize="16" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type ControlViewModels:MenuItemViewModel}">
<ContentControl Content="{Binding ViewModel}" />
</DataTemplate>
</TabControl.ContentTemplate>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
теперь вы можете изменить выбранное TabItem
от родительской модели представления, как это:
MenuItems[0].IsSelected = true;
обратите внимание, что, поскольку это свойство привязано к данным TabItem.IsSelected
собственность, называя это...:
MenuItems[1].IsSelected = true;
... будет infact также автоматически установить MenuItems[0].IsSelected
свойство false
. поэтому, если модель представления, с которой вы работаете, имеет свой IsSelected
свойство имеет значение true, то вы можете быть уверены, что его связанный вид выбран в TabControl
.
вы можете создать привязку между моделью представления и TabControl.SelectedIndex
собственность - т. е. 0 выбирает "первый"!--2--> , 1 выбираем второй, и т. д.
<TabControl DataContext="..." SelectedIndex="{Binding SomeVmProperty}" ...
(в качестве альтернативы, в зависимости от того, как у вас все настроено, вы можете привязаться к SelectedItem
...)
вы, вероятно, захотите использовать какой-то "Событие Агрегатор" шаблон (т. е. the Посланник класс в MVVM Light) для трансляции какого-то" навигационного " сообщения. Ваше представление-TabControl - может прослушивать конкретное сообщение и переходить к Tab2 при получении сообщения.
кроме того, вы можете привязать "SelectedItem" свойство TabControl для вашей ViewModel и просто вызовите CurrentTab = MySecondTabViewModel
из вашей виртуальной машины. Это the подход рекомендуется @HighPoint в комментариях к OP, но я не поклонник; см. ниже. Еще одно предостережение к этому подходу заключается в том, что вы должны быть знакомы с DataTemplates, так как вам нужно будет отобразить вид на каждый ViewModel, который вы отображаете.
Мне лично нравится первый подход, потому что я не считаю его "ответственностью" ViewModel для обработки навигации по вкладкам. Если вы просто предупредите свое представление, когда данные изменятся в вашем ViewModel, вы позволяете представлению решать, хочет ли он изменять вкладки.