WPF Template Selector

From no name for this wiki
Jump to: navigation, search

WPF template selector sample

MainWindow.xaml

<Window x:Class="ControlsTestProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ControlsTestProject"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:MyControlViewModel x:Key="ViewModel"/>
        <local:MyDataTemplateSelector x:Key="TemplateSelector"/>
        <DataTemplate x:Key="Template1">
            <local:MyControl1/>
        </DataTemplate>
        <DataTemplate x:Key="Template2">
            <local:MyControl2/>
        </DataTemplate>
    </Window.Resources>
    <StackPanel DataContext="{StaticResource ViewModel}">
 
        <ListView 
            ItemsSource="{Binding Source={StaticResource ViewModel}, Path=MyItems}"
            ItemTemplateSelector="{StaticResource TemplateSelector}">
        </ListView>
 
    </StackPanel>
</Window>

TemplateSelector

using System.Windows;
using System.Windows.Controls;
 
namespace ControlsTestProject
{
    public class MyDataTemplateSelector : DataTemplateSelector
    {
 
        public MyDataTemplateSelector()
        {
 
        }
 
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;
            MyItemVm myItem = item as MyItemVm;
 
            if(myItem == null || element == null)
            {
                return null;
            }
 
            string resourceKey = string.Empty;
            if(myItem.ItemType == "Type1")
            {
                resourceKey = "Template1";
            }
            else if (myItem.ItemType == "Type2")
            {
                resourceKey = "Template2";
            }
            DataTemplate result = element.FindResource(resourceKey) as DataTemplate;
            return result;
        }
    }
}

MyControl1

<UserControl x:Class="ControlsTestProject.MyControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ControlsTestProject"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBox Text="{Binding Path=ItemName}">
            <TextBox.Background>
                <SolidColorBrush>
                    <SolidColorBrush.Color>
                        Aquamarine
                    </SolidColorBrush.Color>
                </SolidColorBrush>
            </TextBox.Background>
        </TextBox>
    </Grid>
</UserControl>

MyControl2

<UserControl x:Class="ControlsTestProject.MyControl2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ControlsTestProject"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             d:DataContext="{d:DesignInstance Type=local:MyItemVm}">
    <Grid>
        <TextBox Text="{Binding Path=ItemName}" Background="Yellow"/>       
    </Grid>
</UserControl>

ViewModels

using System.Collections.ObjectModel;
using System.ComponentModel;
 
 
namespace ControlsTestProject
{
    public class MyControlViewModel : INotifyPropertyChanged 
    {
 
        public MyControlViewModel()
        {
            MyItems = new ObservableCollection<MyItemVm>();
            for(int i=0; i<30; i++)
            {
                MyItems.Add(new MyItemVm { ItemType = "Type1", ItemName = "" + i++ });
                MyItems.Add(new MyItemVm { ItemType = "Type2", ItemName = "" + i });
            }
        }
 
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        public ObservableCollection<MyItemVm> MyItems { get; set; }
    }
 
    public class MyItemVm
    {
        public string ItemType { get; set; }
 
        public string ItemName { get; set; }
    }
}