最近在WPF项目遇到了需要使用标签页展示一些子页面的需求,搜索之后发现了TabControl控件,发现相当好用,于是在此处整理了一套(自认为)相对通用的解决方案。
标签页容器——TabControl简介
首先看微软官方文档,发现TabControl
继承自ItemsControl
,意味着TabControl
中的子项TabItem
可以通过可观测集合ObservableCollection<TabItem>
进行增删,于是我们就把TabItem
作为容器来放置子标签的页面。
xaml中添加TabControl并绑定到可观测集合
<Window
mc:Ignorable="d"
Title="TabConWindow" Height="450" Width="800">
<Window.DataContext>
<local:TabConViewModel></local:TabConViewModel>
</Window.DataContext>
<Grid>
<TabControl ItemsSource="{Binding TabItems}" >
</TabControl>
</Grid>
</Window>
准备标签页——为UserControl设置DataContext
设置标签页视图——为TabItem
的Content
属性设置UserControl
视图
通过实例化新的TabItem
,并将一个实例化的UserControl
赋值给TabItem
的Content
属性,就实现了将UserControl
的视图绑定到这个新的TabItem
中。
这里我准备了两个UserControl
用来测试
UserControl1.xaml
<UserControl x:Class="TestBed.Views.UserControls.UserControl1"
xmlns:local="clr-namespace:TestBed.Views.UserControls"
xmlns:vm="clr-namespace:TestBed.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<vm:HelloViewModel></vm:HelloViewModel>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Hello}"></TextBlock>
<Button Grid.Row="1" Grid.Column="1" Command="{Binding ChangeCommand}"></Button>
</Grid>
</UserControl>
UserControl2.xaml
<UserControl
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<vm:JojoViewModel></vm:JojoViewModel>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Hello}"></TextBlock>
<Button Grid.Row="1" Command="{Binding ChangeCommand}"></Button>
</Grid>
</UserControl>
将实例化的TabItem添加到可观测集合中
public partial class TabConViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<TabItem> tabItems;
public TabConViewModel()
{
tabItems = new ObservableCollection<TabItem>();
TabItem tabItem = new TabItem();
tabItem.Content = new UserControl1();
TabItem tabItem2 = new TabItem();
tabItem2.Content = new UserControl2();
tabItems.Add(tabItem);
tabItems.Add(tabItem2);
tabItem.Header = "Hello1";
tabItem2.Header = "Hello2";
}
}
效果
结论
通过设置TabControl
的ItemsSource
属性绑定到一个ObservableCollection<TabItem>
,在这个集合中增删添加了视图内容(通常用绑定了DataContext
的UserControl
来实现)TabItem
可以实现动态添加自定义的子标签页