c# - 以编程方式在 TabItem 中加载 UserControl

标签 c# wpf xaml mvvm

使用 XAML 时,将 UserControl 放置在 TabItem 中是非常基本的。

<TabControl>
    <TabItem>
        <local:MyUserControl/>
    </TabItem>
</TabControl>

但是假设我想使用 ViewModel 加载 UserControl。我该怎么做呢?例如
<TabControl ItemsSource="{Binding TabCollection}">
    <TabItem Header="{Binding Header}"
             Source="{Binding MyUserControl}"> <!-- Source is obviously not a property of TabItem-->
                                               <!-- I'm just using it in this context as an example. Like how a 'Frame' would work -->
    </TabItem>
</TabControl>

假设我的 ViewModel 有一个 ObservableCollection 用于填充不同的选项卡、标题、背景颜色等,我将如何以编程方式在 TabItem 中填充 View ?

例如,下面是 ViewModel 的基本示例:
public class TabViewModel
{
    // 'TabModel' is a simple class that acts as a Model for this class (TabViewModel)
    // All it does is store strings, integers, etc. as properties
    // i.e: the fields 'Header' and 'MyUserControl' in the below method are both strings declared in 'TabModel'
    public ObservableCollection<TabModel> TabCollection { get; set; }

    public TabViewModel()
    {
        TabCollection = new ObservableCollection<TabModel>();
        PopulateTabCollection();
    }

    private void PopulateTabCollection()
    {
        TabCollection.Add(new TabModel()
        {
            Header = "FirstUserControl",
            MyUserControl = "Views/MyFirstUserControl.xaml"
        });

        TabCollection.Add(new TabModel()
        {
            Header = "SecondUserControl",
            MyUserControl = "Views/MySecondUserControl.xaml"
        });
    }
}

所以我需要做的是通过数据绑定(bind)在每个Tab中显示不同的 View 。我什至不确定这是否可能。但如果是的话,请教育我。

最佳答案

您可以使用 DataTemplates 来实现这一点。请引用以下代码。

<Window.Resources>
    <DataTemplate DataType="{x:Type local:PersonVm}">
        <local:Person/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:DeptVm}">
        <local:Department/>
    </DataTemplate>
</Window.Resources>
<Grid>
    <TabControl ItemsSource="{Binding TabCollection}" SelectedIndex="0">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding TabName}"/>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ContentControl  Content="{Binding }"/>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Grid>


public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new TabViewModel();
        }
    }

    public class TabViewModel
    {
        public ObservableCollection<object> TabCollection { get; set; }

        public TabViewModel()
        {
            TabCollection = new ObservableCollection<object>();
            PopulateTabCollection();
        }

        private void PopulateTabCollection()
        {
            TabCollection.Add(new PersonVm()
            {
                PersonName = "FirstUserControl",
                Address = "Address",
                TabName = "Person Tab"
            });

            TabCollection.Add(new DeptVm()
            {
                DeptName = "SecondUserControl",
                TabName = "DeptTab"
            });
        }
    }

    public class PersonVm
    {
        public string PersonName { get; set; }
        public string Address { get; set; }
        public string TabName { get; set; }

    }

    public class DeptVm
    {
        public string DeptName { get; set; }
        public string TabName { get; set; }
    }

关于c# - 以编程方式在 TabItem 中加载 UserControl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38460655/

相关文章:

c# - WPF网格白色条纹

c# - 具有延迟和键绑定(bind)的 XAML 绑定(bind)

c# - 使用用户定义的名称创建新方法。反射 C#

c# - C# 中 Action 委托(delegate)的使用

c# - 如何通过 ViewModel 调用自定义控件上的方法

wpf - 按钮命令未在 ListView 组标题中触发

c# - 如何与框架page.xaml通信

c# - 如果一个对象具有相同的接口(interface),是否可以动态地将一个对象的内容复制到另一个对象?

c# - 如何正确检测主题窗口的角半径

c# - 当我尝试更改 WPF 中 ItemsControl 的宽度时出现 UI 性能问题