[WPF]ItemsControl模板切換 簡例

  • 2022
  • 0
  • 2014-07-09

[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-藍小火-歡迎指正及分享