使用 TabControl (MVVM) 显示不同的 ViewModel

Posted

技术标签:

【中文标题】使用 TabControl (MVVM) 显示不同的 ViewModel【英文标题】:Show different ViewModels with TabControl (MVVM) 【发布时间】:2021-09-23 05:54:04 【问题描述】:

我编写了一个具有不同 ViewModel 的应用程序,一个用于用户、组和机器。每个 ViewModel 都有自己的 View。我正在使用 Caliburn.Micro。 现在我像这样在带有按钮的视图之间切换:

XAML:

     <StackPanel Orientation="Horizontal">
                <Button VerticalAlignment="Top" Margin="5" Height="30" x:Name="ShowUsers" Content="Users"/>
                <Button VerticalAlignment="Top" Margin="5" Height="30" x:Name ="ShowGroups" Content="Groups"/>
                <Button VerticalAlignment="Top" Margin="5" Height="30" x:Name ="ShowMachines" Content="Machines"/>
            </StackPanel>
<ContentControl Grid.Row="1" x:Name="ActiveItem"/>

C#:

public AdminViewModel(GroupManagementViewModel groupManagementViewMode, MachineManagementViewModel machineManagementViewModel, UserManagementViewModel userManagementViewModel)
        
            this._groupManagementViewModel = groupManagementViewMode;
            this._machineManagementViewModel = machineManagementViewModel;
            this._userManagementViewModel = userManagementViewModel;
        

        protected override void OnActivate()
        
            base.OnActivate();
            ShowUsers();
        

        public void ShowUsers()
        
            ActivateItem(_userManagementViewModel);
        

        public void ShowGroups()
        
            ActivateItem(_groupManagementViewModel);
        

        public void ShowMachines()
        
            ActivateItem(_machineManagementViewModel);

我想使用 TabControl 更改这些按钮,我尝试了几件事,现在我的代码如下所示:

XAML(带 Tabcontrol):

<TabControl>
            <TabItem Header="User" x:Name="ShowUsers">
               
            </TabItem>
            
            <TabItem Header="Groups" x:Name="ShowGroups">
                
            </TabItem>
            <TabItem Header="Machines" x:Name="ShowMachines">
              
            </TabItem>
           
        </TabControl>
        <ContentControl Grid.Row="1" x:Name="ActiveItem"/>

所以我在 ViewModel 中为 TabItems 提供了命令的 x:Name,但它只为每个 TAB 显示相同的视图模型

我会非常感谢每一个提示。

最好的问候

扎因

【问题讨论】:

【参考方案1】:

TabControl 元素有一个 ItemSource 属性,可用于完成这项工作。例如:

您可以将 ItemSource 绑定到一个类型的可观察集合,该类型是您要在选项卡控件中使用的所有三个 viewModel 的基类:

public ObservableCollection<BaseViewModel> TabControlViewModels  get; 

ItemSource 将绑定到此。

查看 TabControl (ItemsControl) 可能对以下方面有所帮助:SelectedIndex、ItemsPanel、ItemTemplate 和 ItemContainerStyle,使其看起来符合您的要求。

更多详情请参见此处:How do I bind a TabControl to a collection of ViewModels?

【讨论】:

没问题!很高兴为您提供帮助【参考方案2】:

使用 Caliburn.Micro,视图中的 XAML 标记应该像这样简单:

<TabControl x:Name="Items" />

然后视图模型应该从Conductor&lt;T&gt;.Collection.OneActive 继承并将标签视图模型添加到Items 属性:

public class AdminViewModel : Conductor<object>.Collection.OneActive

    public AdminViewModel(GroupManagementViewModel groupManagementViewMode, 
        MachineManagementViewModel machineManagementViewModel, 
        UserManagementViewModel userManagementViewModel)
    
        Items.Add(groupManagementViewMode);
        Items.Add(machineManagementViewModel);
        Items.Add(userManagementViewModel);
    

标签视图模型应该继承自Screen。然后您可以设置它们的DisplayName 属性来修改选项卡标题。

【讨论】:

非常感谢它完美运行。一般来说,我对 Caliburn.Micro 和 WPF 比较陌生。我在 ViewModel 中创建了 IHaveDisplayName 属性,但现在如何更改 Tab 标题? 设置Screen基类的DisplayName属性。 所以我将 DisplayName 设置为这样 [DisplayName("Users")] 但它不起作用。我想我的回答完全错误 GroupManagementViewModel 是否继承自 Screen 那么它有一个DisplayName可以设置的属性; this.DisplayName = "header..".

以上是关于使用 TabControl (MVVM) 显示不同的 ViewModel的主要内容,如果未能解决你的问题,请参考以下文章

使用 MVVM 将新项目添加到 TabControl ItemSsource 时选择最后一个 TabItem

TabControl 怎么每点击一个TabItem 就在同一个Tabcontrol中显示不同的页面?

使用 MVVM 模式的 UI 设计

如何将 TabControl 绑定到 ViewModel 集合?

C# WPF MVVM项目实战(进阶①)

C# winform中TabControl怎么在每个选项卡的卡头添加不同的图标