Load UserControl in TabItem programmatically

2019-07-29 11:40发布

Placing a UserControl inside a TabItem is pretty basic when using XAML.

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

But say I want to load the UserControl using the ViewModel. How would I go about that? For instance

<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>

Assuming My ViewModel has an ObservableCollection that I use to populate the different Tabs, Headers, Background colour and so on, how would I populate a view in the TabItem programmatically?

For instance, Below is a basic sample of the 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"
        });
    }
}

So what I need to do is display a different view in each Tab through databinding. I'm not even sure if this is even possible. But if it is, kindly educate me.

标签: c# wpf xaml mvvm
1条回答
ら.Afraid
2楼-- · 2019-07-29 12:19

You can achieve this using DataTemplates. Refer the below code.

<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; }
    }
查看更多
登录 后发表回答