WPF

Quick Tips to use WPF ListView ItemTemplateSelector

WPF ListView ItemTemplateSelector is used for choosing a DataTemplate for each ListViewItem at runtime. You can provide a custom logic to choose which DataTemplate to use in list view item.

When to use?

You have to show different UIs for each ListViewItem based on some condition. But using the ItemTemplate you can only set only one DataTemplate which is used by every ListViewItem. ItemTemplateSelector provides you an option for setting different DataTemplates at runtime for each ListViewItem based on your custom logic.

You can only assign DataTemplateSelector object to an ItemTemplateSelector property of ListView.

What is DataTemplateSelector?

DataTemplateSelector is a class which provides a single method SelectTemplate. This SelectTemplate method provides you a place for writing custom logic to select different DataTemplates.

public class DataTemplateSelector
{
	public virtual DataTemplate SelectTemplate(object item, DependencyObject container);
}

You can inherit from DataTemplateSelector and override the SelectTemplate method.

When WPF ListView item is creating its list view item, it’s automatically called this SelectTemplate method for getting its DataTemplate and use that DataTemplate for rendering it’s UI.

You can not define both ItemTemplateSelector and ItemTemplate property. If ItemTemplate property is set, it’s automatically ignores the ItemTemplateSelector property.

ItemTemplateSelector example

In this example, I have defined two DataTemplates name ‘NormalUserDataTemplate’ and ‘PremiumUserDataTemplate’ and create a class ‘PremiumUserDataTemplateSelector’ which inherits from DataTemplateSelector which runtime choose between these two DataTemplates based on PremiumUser property. If user is PremiumUser then show ‘PremiumUserDataTemplate’ else show ‘NormalUserDataTemplate’.

I have created an instance of PremiumUserDataTemplateSelector in the Window resources section and set it as a StaticResource in ItemTemplateSelector property of ListView.

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication5"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate x:Key="NormalUserDataTemplate">
            <StackPanel>
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="PremiumUserDataTemplate">
            <StackPanel Background="LightBlue">
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
        <local:PremiumUserDataTemplateSelector x:Key="myPremiumUserDataTemplateSelector" />
    </Window.Resources>
    <Grid>
        <ListView x:Name="myListView" ItemTemplateSelector="{StaticResource myPremiumUserDataTemplateSelector}">
        </ListView>
    </Grid>
</Window>

public partial class MainWindow : Window
{
	public MainWindow()
	{
		InitializeComponent();

		List<User> users = new List<User>();
		for (int i = 0; i < 10; ++i)
		{
			var user = new User { ID = i, Name = "Name " + i.ToString(), Age = 20 + i };
			if (i == 2 || i == 4)
			{
				user.IsPremiumUser = true;
			}
			users.Add(user);
		}
		myListView.ItemsSource = users;
	}
}

public class PremiumUserDataTemplateSelector : DataTemplateSelector
{
	public override DataTemplate SelectTemplate(object item, DependencyObject container)
	{
		FrameworkElement elemnt = container as FrameworkElement;
		User user = item as User;
		if(user.IsPremiumUser)
		{
			return elemnt.FindResource("PremiumUserDataTemplate") as DataTemplate;
		}
		else
		{
			return elemnt.FindResource("NormalUserDataTemplate") as DataTemplate;
		}
	}
}

public class User
{
	public int ID { get; set; }
	public string Name { get; set; }
	public int Age { get; set; }
	public bool IsPremiumUser { get; set; }
}
WPF ListView ItemTemplateSelector Example