[WPF]ItemsContrl模板切換 簡例
範例環境:
WPF 基類 參考: Caliburn.Micro.PropertyChangedBase
範例說明:
將客戶,與機器人 放在同一個ListView內顯示,並以不同顯示(模板 Template)方式來區分(Selector Template)。
有兩範例 情境相同,不同做法。
DomainObject:
//客戶
public class Customer : Caliburn.Micro.PropertyChangedBase { public string Name { get { return _name; } set { _name = value; NotifyOfPropertyChange(() => Name); } } private string _name; public string Profession { get; set; } public Customer(string name, string profession) { Name = name; Profession = profession; } }
//機器人
public class Robot : Caliburn.Micro.PropertyChangedBase { public string Name { get { return _name; } set { _name = value; NotifyOfPropertyChange(() => Name); } } private string _name; public string Id { get; set; } public Robot(string name, string id) { Name = name; Id = id; } }
情境1:
依ListItem的型別來判斷選用那個模板(由xaml中定義)。
備註:CompositeCollection 型別:讓多個集合和項目顯示為單一清單。白話來說就是將多個集合,合併成一個大集合。以下為範例程式碼:
public class MainWindowViewModel : Caliburn.Micro.PropertyChangedBase
{ public CompositeCollection Datas { get { return _dates; } set { _dates = value; NotifyOfPropertyChange(() => Datas); } } private CompositeCollection _dates; public MainWindowViewModel() { ListCollectionView data = new ListCollectionView(new ObservableCollection<Customer>(new Customer[] { new Customer("Hans", "Programmer") , new Customer("Elister", "Programmer") , new Customer("Steve", "GUI Designer") , new Customer("Stephen", "GUI Designer") , new Customer("Joe", "Coffee Getter") , new Customer("Julien", "Programmer") , new Customer("John", "Coffee Getter") , })); ; ObservableCollection<Robot> data2 = new ObservableCollection<Robot>(new Robot[] { new Robot("XI2", String.Empty), new Robot("MK2-xx", String.Empty), new Robot("A2-B16", String.Empty), }); CompositeCollection cc1 = new CompositeCollection(); cc1.Add(new CollectionContainer() { Collection = data }); cc1.Add(new CollectionContainer() { Collection = data2 }); Datas = cc1; } }
//MainWindow.xaml
<Window x:Class="ItemsControlBySelectorTemplate.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vms="clr-namespace:ItemsControlBySelectorTemplate" Title="MainWindow" Height="350" Width="525"> <Window.DataContext> <vms:MainWindowViewModel /> </Window.DataContext> <Grid> <ListView ItemsSource="{Binding Datas}"> <ListView.Resources> <!-- 不要設定key,將依照Items類型來匹配DataTemplate--> <DataTemplate DataType="{x:Type vms:Customer}" > <TextBlock Text="{Binding Name}" Foreground="Blue"/> </DataTemplate> <DataTemplate DataType="{x:Type vms:Robot}" > <TextBlock Text="{Binding Name}" Foreground="Red"/> </DataTemplate> </ListView.Resources> </ListView> </Grid> </Window>
顯示:
情境2:
依集合類型的來判斷選用那個指定模板(DataTemplateSelector 來選擇一個對應模板)。
以下為範例程式碼:
public MainWindowViewModel() { List<Customer> data = new List<Customer>() { new Customer("Hans", "Programmer") , new Customer("Elister", "Programmer") , new Customer("Steve", "GUI Designer") , new Customer("Stephen", "GUI Designer") , new Customer("Joe", "Coffee Getter") , new Customer("Julien", "Programmer") , new Customer("John", "Coffee Getter") , }; List<Robot> data2 = new List<Robot>() { new Robot("XI2", String.Empty), new Robot("MK2-xx", String.Empty), new Robot("A2-B16", String.Empty), }; Datas = new ListCollectionView(new List<Object>() { data, data2 }); }
//MainWindow.xaml
<Window x:Class="RoutedTemplateSelection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vms="clr-namespace:RoutedTemplateSelection" Title="MainWindow" Height="350" Width="525"> <Window.DataContext> <vms:MainWindowViewModel /> </Window.DataContext> <Window.Resources> <vms:RoutedDataTemplateSelector x:Key="PersonTemplateSelector" /> <DataTemplate x:Key="RegularTemplate"> <ListView ItemsSource="{Binding}" DisplayMemberPath="Name" Foreground="Red"/> </DataTemplate> <DataTemplate x:Key="ReportTemplate"> <ListView ItemsSource="{Binding}" DisplayMemberPath="Name" Foreground="Blue" /> </DataTemplate> </Window.Resources> <Grid> <ListView ItemsSource="{Binding Datas}" ItemTemplateSelector="{StaticResource PersonTemplateSelector}" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" /> </Grid> </Window>
//模板選擇器 //依集合類型指定特定的模板 public class RoutedDataTemplateSelector : DataTemplateSelector { public override DataTemplate SelectTemplate( object item, DependencyObject container) { FrameworkElement elem = container as FrameworkElement; var items = item as IEnumerable; if (items == null) { return elem.FindResource("RegularTemplate") as DataTemplate; } var listItems = items.OfType<Robot>(); if (listItems.Any()) return elem.FindResource("RegularTemplate") as DataTemplate; else return elem.FindResource("ReportTemplate") as DataTemplate; } }
顯示:
小伙製作範例-檔案連結:
https://www.dropbox.com/s/t0ngl55g4vd258e/ItemsControlBySelectorTemplate.zip
By-藍小火-歡迎指正及分享