小编典典

如何将TabControl绑定到ViewModels的集合?

c#

基本上我在MainViewModel.cs中:

ObservableCollection<TabItem> MyTabs { get; private set; }

但是,我需要以某种方式不仅可以创建选项卡,还可以在维护MVVM的同时将选项卡的内容加载并链接到其相应的视图模型。

基本上,我如何才能将用户控件作为Tabitem的内容加载,并使该用户控件连接到适当的视图模型。造成这一困难的部分是ViewModel不应构造实际的视图项,对吗?可以吗

基本上,这是否适合MVVM:

UserControl address = new AddressControl();
NotificationObject vm = new AddressViewModel();
address.DataContext = vm;
MyTabs[0] = new TabItem()
{
    Content = address;
}

我只问是因为好,我是在ViewModel中构造一个View(AddressControl),对我来说这听起来像是MVVM禁止。


阅读 318

收藏
2020-05-19

共1个答案

小编典典

这不是MVVM。您不应该在视图模型中创建UI元素。

您应该将Tab的ItemsSource绑定到ObservableCollection,并且该模型应包含带有应创建的选项卡信息的模型。

这是代表选项卡页面的VM和模型:

public sealed class ViewModel
{
    public ObservableCollection<TabItem> Tabs {get;set;}
    public ViewModel()
    {
        Tabs = new ObservableCollection<TabItem>();
        Tabs.Add(new TabItem { Header = "One", Content = "One's content" });
        Tabs.Add(new TabItem { Header = "Two", Content = "Two's content" });
    }
}
public sealed class TabItem
{
    public string Header { get; set; }
    public string Content { get; set; }
}

这是绑定在窗口中的外观:

<Window x:Class="WpfApplication12.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <ViewModel
            xmlns="clr-namespace:WpfApplication12" />
    </Window.DataContext>
    <TabControl
        ItemsSource="{Binding Tabs}">
        <TabControl.ItemTemplate>
            <!-- this is the header template-->
            <DataTemplate>
                <TextBlock
                    Text="{Binding Header}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <!-- this is the body of the TabItem template-->
            <DataTemplate>
                <TextBlock
                    Text="{Binding Content}" />
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Window>

(请注意,如果要在不同的选项卡中使用不同的内容,请使用DataTemplates。每个选项卡的视图模型应该是其自己的类,或者创建一个自定义DataTemplateSelector来选择正确的模板。)

数据模板内部的UserControl:

<TabControl
    ItemsSource="{Binding Tabs}">
    <TabControl.ItemTemplate>
        <!-- this is the header template-->
        <DataTemplate>
            <TextBlock
                Text="{Binding Header}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <!-- this is the body of the TabItem template-->
        <DataTemplate>
            <MyUserControl xmlns="clr-namespace:WpfApplication12" />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>
2020-05-19