Posted by: Zeeshan Amjad | August 23, 2010

Apply conditional data template in Data Grid


We saw one example of applying data template conditionally here. Now we are going to apply the data template conditionally on data grid. The main difference between these two articles are that here we are not going to define data template for whole grid. But we are going to define the data template on only one column of the grid.

First we have to inherit class from DataTemplateSelector. Here is a simple implementation of this, where we are going to select one data template out of two depends on the data.

public class GradeTemplateSelector : DataTemplateSelector
{
    public DataTemplate PassedTemplate
    { get; set; }

    public DataTemplate FailedTemplate
    { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        Student student = item as Student;

        if (student != null)
        {
            if (student.Percentage >= 60)
                return PassedTemplate;
            else
                return FailedTemplate;
        }
        else            
            return base.SelectTemplate(item, container);
    }
}


In next step we are going to define two data template in our XAML. Here is simple implementation of our two data templates.

<Window.Resources>
	<DataTemplate x:Key="PassedTemplate">
		<TextBlock Margin="2" Text="Passed" Foreground="Green"/>
	</DataTemplate>
	<DataTemplate x:Key="FailedTemplate">
		<TextBlock Margin="2" Text="Failed" Foreground="Red"/>
	</DataTemplate>
</Window.Resources>

By applying data template on only one columns not on the whole grid, we are going to use the cell template selector property of data grid template columns. Here is a XAML code to do this.

<DataGridTemplateColumn Header="Grade">
	<DataGridTemplateColumn.CellTemplateSelector>
		<local:GradeTemplateSelector 
			PassedTemplate="{StaticResource PassedTemplate}"
			FailedTemplate="{StaticResource FailedTemplate}"/>
	</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>

Note that we are not creating object of our GrateTemplateSelctor class inside the resource section, but we created it when we are going to apply the template selector. Also note one more difference that in conditional data template, we are displaying text that is not even included in the data.

This is very simple example and we can do this with other method too, like user converter to display appropriate text and trigger to set its color. But here the whole purpose of this exercise is to demonstrate how to apply conditional data template to only one columns of a data grid at a time. Here is complete XAML code of the program.

<Window x:Class="WpfDataGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfDataGrid"
        Title="Data Grid" Height="300" Width="400">
    <Window.Resources>
        <DataTemplate x:Key="PassedTemplate">
            <TextBlock Margin="2" Text="Passed" Foreground="Green"/>
        </DataTemplate>
        <DataTemplate x:Key="FailedTemplate">
            <TextBlock Margin="2" Text="Failed" Foreground="Red"/>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <DataGrid ItemsSource="{Binding}"
                  AlternationCount="2" AlternatingRowBackground="AliceBlue" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Student ID" Binding="{Binding ID}"/>
                <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/>
                <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"/>
                <DataGridTemplateColumn Header="Percentage">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ProgressBar Margin="2" Minimum="0" Maximum="100" Value="{Binding Percentage}">
                                <ProgressBar.ToolTip>
                                    <TextBlock Text="{Binding Percentage}"/>
                                </ProgressBar.ToolTip>
                            </ProgressBar>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Grade">
                    <DataGridTemplateColumn.CellTemplateSelector>
                        <local:GradeTemplateSelector 
                            PassedTemplate="{StaticResource PassedTemplate}"
                            FailedTemplate="{StaticResource FailedTemplate}"/>
                    </DataGridTemplateColumn.CellTemplateSelector>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

and here is complete C# code of the program.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace WpfDataGrid
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ObservableCollection<Student> students = new ObservableCollection<Student>();

        public MainWindow()
        {
            InitializeComponent();

            students.Add(new Student(10, "Bob", "Smith", 80.5));
            students.Add(new Student(25, "James", "Brown", 77.9));
            students.Add(new Student(15, "Joe", "Martin", 52.4));
            students.Add(new Student(12, "Dona", "Taylor", 53.6));
            students.Add(new Student(18, "Peter", "Brian", 90.9));

            DataContext = students;
        }
    }

    public class GradeTemplateSelector : DataTemplateSelector
    {
        public DataTemplate PassedTemplate
        { get; set; }

        public DataTemplate FailedTemplate
        { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            Student student = item as Student;

            if (student != null)
            {
                if (student.Percentage >= 60)
                    return PassedTemplate;
                else
                    return FailedTemplate;
            }
            else            
                return base.SelectTemplate(item, container);
        }
    }

    public class Student
    {
        public Student(int id, String firstName, String lastName, Double percentage)
        {
            ID = id;
            FirstName = firstName;
            LastName = lastName;
            Percentage = percentage;
        }

        public int ID
        { get; set; }

        public String FirstName
        { get; set; }

        public String LastName
        { get; set; }

        public Double Percentage
        { get; set; }
    }
}

Here is the output of the program.

ConditionalTemplateDataGrid

Advertisements

Responses

  1. I’m completely in the favor of Mr. Zeeshan’s recommendations about conditional data template in data grid.In order to read more about data grid you can visit on http://dapfor.com/en/net-suite/net-grid

    • Thanks for visiting my blog and pointing us towards this useful grid.

      Regards
      Zeeshan Amjad

  2. Hi Zeeshan,
    you have written a nice article, but the article is based on static datagrid where all columns are fixed, i am working with the similar scenario but mu datagrid is dynamic, where i can’t create & bind templatecolumn in XAML, please let me know how can i do it in code behind (c#).

    Manoj Shukla

    • Hi Manoj

      You mean you are creading data grid with code? You can always create template using your code, but it is not recommended way. In fact i have an example in my blog to just demonstrate this. Please corrent me if didn’t understand your question.

      Regards
      Zeeshan Amjad

  3. Hi Zeeshan,

    It is a very nice article. Could you let me know please how to copy data to clipboard from CellTemplateSelector? Thank you very much.

    Regards,

    Johny


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: