在以前的開發過程中,對于TabControl
控件,我一般是習慣直接定義TabItem
,在TabItem
下布局,并進行綁定。
類似這樣
1 <TabControl ItemsSource="{Binding TabList}" SelectedIndex="0">2 <TabItem Header="Tab1">3 <Grid>4 <Label Content="{Binding XXX}"/>5 </Grid>6 </TabItem>7 <TabItem Header="Tab2">8 <Grid>9 <Button Content="{Binding XXX}" Command="{Binding XXX}"/> 10 </Grid> 11 </TabItem> 12 </TabControl>
我們也可以單獨定義每一個Tab頁的ViewModel和布局。
1、創建一個Tab頁公用的ViewModel
這個類用于顯示Tab頁的標題等公共屬性。
1 public class TabViewModel : ObservableObject2 {3 private string headerName;4 5 public string HeaderName 6 { 7 get => headerName; 8 set => SetProperty(ref headerName,value); 9 } 10 }
2、定義每一個Tab頁的ViewModel
假設我這里是設置兩頁,TabA
和TabB
TabA
顯示一個詳情文本
TabB
顯示一個圖片
TabToolAViewModel.cs
1 public class TabToolAViewModel : TabViewModel2 {3 private string detail;4 public string Detail { get => detail; set => SetProperty(ref detail,value); }5 6 public TabToolAViewModel()7 {8 HeaderName = "工具A";9 } 10 11 }
TabToolBViewModel.cs
1 public class TabToolBViewModel : TabViewModel2 {3 private string imagePath;4 public string ImagePath { get => imagePath; set => SetProperty(ref imagePath,value); }5 6 public TabToolBViewModel()7 {8 HeaderName = "工具B";9 } 10 11 }
3、創建主界面
MainWindow.xaml
1 <Window x:Class="WPFTabMVVMDemo.MainWindow"2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"6 mc:Ignorable="d"7 Title="MainWindow" Height="450" Width="800">8 <TabControl ItemsSource="{Binding TabList}" SelectedIndex="0">9 <TabControl.ItemTemplate> 10 <DataTemplate> 11 <ContentPresenter Content="{Binding HeaderName}"></ContentPresenter> 12 </DataTemplate> 13 </TabControl.ItemTemplate> 14 </TabControl> 15 </Window>
4、創建主界面的ViewModel
MainWindowViewModel.cs
1 public class MainWindowViewModel : ObservableObject2 {3 private ObservableCollection<TabViewModel> tabList = new ObservableCollection<TabViewModel>();4 5 public ObservableCollection<TabViewModel> TabList { get => tabList; set => SetProperty(ref tabList,value); }6 7 public MainWindowViewModel()8 {9 tabList.Add(new TabToolAViewModel() {Detail = "詳情...." }); 10 tabList.Add(new TabToolBViewModel() { ImagePath = "https://img2.baidu.com/it/u=3115165460,1153722234&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750" }); 11 } 12 13 }
我們將MainWindowViewModel.cs
綁定到MainWindow
上后
1 public MainWindow() 2 { 3 InitializeComponent(); 4 5 this.DataContext = new MainWindowViewModel(); 6 }
運行效果如下:
可以看到這里顯示的是TabToolAViewModel
的字樣,因為這里TabToolAViewModel
并沒有對應到具體的View上面。
5、創建單獨的視圖
接下來我們就可以單獨的創建每個Tab頁要顯示的內容了
TabAView.xaml
TabA
顯示一個詳情文本
1 <UserControl x:Class="WPFTabMVVMDemo.Views.ToolAView"2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:WPFTabMVVMDemo.Views"7 mc:Ignorable="d" 8 d:DesignHeight="450" d:DesignWidth="800">9 <StackPanel> 10 <Label Content="{Binding Detail}"></Label> 11 </StackPanel> 12 </UserControl>
TabBView.xaml
TabB
顯示一個圖片
1 <UserControl x:Class="WPFTabMVVMDemo.Views.ToolBView"2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:WPFTabMVVMDemo.Views"7 mc:Ignorable="d" 8 d:DesignHeight="450" d:DesignWidth="800">9 <Grid> 10 <Image Source="{Binding ImagePath}"></Image> 11 </Grid> 12 </UserControl>
6、創建視圖和ViewModel的映射
有了兩個單獨的視圖以后,如何將它和它們對應的ViewModel
綁定起來呢?
此時我們可以創建一個資源字典,并定義數據模板,用于ViewModel
和View
的映射?
ViewTemplate.xaml
1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"2 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:view="clr-namespace:WPFTabMVVMDemo.Views"3 xmlns:local="clr-namespace:WPFTabMVVMDemo">4 5 <DataTemplate 6 DataType="{x:Type 7 local:TabToolAViewModel}">8 <view:ToolAView></view:ToolAView>9 </DataTemplate> 10 11 <DataTemplate 12 DataType="{x:Type 13 local:TabToolBViewModel}"> 14 <view:ToolBView></view:ToolBView> 15 </DataTemplate> 16 </ResourceDictionary>
7、使用視圖和ViewModel的映射?
然后在需要使用的地方,引用 這個資源字典就可以了。
我們這里是在主窗口中使用
就在MainWindow.xml
中添加如下引用?
1 <Window.Resources> 2 <ResourceDictionary Source="ViewTemplate.xaml"></ResourceDictionary> 3 </Window.Resources>
添加后,運行效果如下:
這樣我們就可以將TabControl
綁定到一個列表,并單獨指定每一個Tab頁的標題和內容。
示例代碼
下載