WPF在MVVM模式中实现为TabControl动态添加标签页
最近在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可以实现动态添加自定义的子标签页
浙公网安备 33010602011771号