Posted by: Zeeshan Amjad | February 3, 2010

Apply Control Template Conditionally


We have already seen an example of apply data template conditionally and apply style conditionally. Now we are going to extent our concept and apply control template conditionally.

Our fist step is to figure out where we can apply the control template. We can apply control template only Control or it’s child class, because control template is define there.

Template_03

We are going to apply different control template on list box item. Listbox item is a child class of control so we can apply the control template to it.

Our first step is to define control templates in XAML. But here we are using one small trick. Rather than defining the control template we are going to define the style which define and set the control template. By using this technique we will use the same technique which we used to define the style conditionally. Here is our first style to define control template for Math subjects.

  1: <Style x:Key="MathStyle" TargetType="ListBoxItem">
  2: 	<Setter Property="Margin" Value="5"/>
  3: 	<Setter Property="Height" Value="20"/>
  4: 	<Setter Property="Template">
  5: 		<Setter.Value>
  6: 			<ControlTemplate TargetType="{x:Type ListBoxItem}">
  7: 				<Grid>
  8: 					<Ellipse Width="{TemplateBinding Width}"
  9: 						 Height="{TemplateBinding Height}" Fill="LightBlue"/>
 10: 					<ContentPresenter VerticalAlignment="Center" 
 11: 						 HorizontalAlignment="Center"/>
 12: 				</Grid>
 13: 			</ControlTemplate>
 14: 		</Setter.Value>
 15: 	</Setter>
 16: </Style>
 17: 

Similarly we define style for Computer Subject.

  1: <Style x:Key="ComputerStyle" TargetType="ListBoxItem">
  2: 	<Setter Property="Margin" Value="5"/>
  3: 	<Setter Property="Height" Value="20"/>
  4: 	<Setter Property="Template">
  5: 		<Setter.Value>
  6: 			<ControlTemplate TargetType="{x:Type ListBoxItem}">
  7: 				<Grid>
  8: 					<Rectangle Width="{TemplateBinding Width}"
  9: 						 Height="{TemplateBinding Height}" Fill="Wheat"/>
 10: 					<ContentPresenter VerticalAlignment="Center" 
 11: 						 HorizontalAlignment="Center"/>
 12: 				</Grid>
 13: 			</ControlTemplate>
 14: 		</Setter.Value>
 15: 	</Setter>
 16: </Style>
 17: 

Now we inherit class from StyleSelector and over ride StyleSelect method. Here is a code of our class.

  1: public class MyStyleSelector : StyleSelector
  2: {
  3:     public Style MathStyle
  4:     { get; set; }
  5: 
  6:     public Style ComputerStyle
  7:     { get; set; }
  8: 
  9:     public override Style SelectStyle(object item, DependencyObject container)
 10:     {
 11:         Student student = item as Student;
 12: 
 13:         if (student != null)
 14:         {
 15:             if (student.Department == 100)
 16:                 return MathStyle;
 17: 
 18:             if (student.Department == 200)
 19:                 return ComputerStyle;
 20:         }
 21:         return base.SelectStyle(item, container);
 22:     }
 23: }
 24: 

Then we create object of this class and set its properties in XAML.

  1: <local:MyStyleSelector x:Key="myTStyleSelectorObj"
  2: 	MathStyle="{StaticResource MathStyle}"
  3: 	ComputerStyle="{StaticResource ComputerStyle}"/>
  4: 

And finally we use our new class to set ItemContainerStyleSelector.

  1: <ListBox Name="list" Margin="5" 
  2: 		 ItemContainerStyleSelector="{StaticResource myTStyleSelectorObj}">
  3: 	<ListBox.ItemTemplate>
  4: 		<DataTemplate>
  5: 			<TextBlock Text="{Binding Path=Subject}"/>
  6: 		</DataTemplate>
  7: 	</ListBox.ItemTemplate>
  8: </ListBox>
  9: 

 

Note that we also define data template here. This is because we set the list of student class as an items source and if we don’t define the binding with appropriate path then we will see the class name not its data.

Here is complete XAML code of our program.

  1: <Window x:Class="WpfControlTemplate.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4:     xmlns:local="clr-namespace:WpfControlTemplate"
  5:     Title="Control Template" Height="300" Width="300">
  6:     <Window.Resources>
  7:         <Style x:Key="MathStyle" TargetType="ListBoxItem">
  8:             <Setter Property="Margin" Value="5"/>
  9:             <Setter Property="Height" Value="20"/>
 10:             <Setter Property="Template">
 11:                 <Setter.Value>
 12:                     <ControlTemplate TargetType="{x:Type ListBoxItem}">
 13:                         <Grid>
 14:                             <Ellipse Width="{TemplateBinding Width}"
 15:                                      Height="{TemplateBinding Height}" Fill="LightBlue"/>
 16:                             <ContentPresenter VerticalAlignment="Center" 
 17:                                               HorizontalAlignment="Center"/>
 18:                         </Grid>
 19:                     </ControlTemplate>
 20:                 </Setter.Value>
 21:             </Setter>
 22:         </Style>
 23:         <Style x:Key="ComputerStyle" TargetType="ListBoxItem">
 24:             <Setter Property="Margin" Value="5"/>
 25:             <Setter Property="Height" Value="20"/>
 26:             <Setter Property="Template">
 27:                 <Setter.Value>
 28:                     <ControlTemplate TargetType="{x:Type ListBoxItem}">
 29:                         <Grid>
 30:                             <Rectangle Width="{TemplateBinding Width}"
 31:                                      Height="{TemplateBinding Height}" Fill="Wheat"/>
 32:                             <ContentPresenter VerticalAlignment="Center" 
 33:                                               HorizontalAlignment="Center"/>
 34:                         </Grid>
 35:                     </ControlTemplate>
 36:                 </Setter.Value>
 37:             </Setter>
 38:         </Style>
 39:         <local:MyStyleSelector x:Key="myTStyleSelectorObj"
 40: 	        MathStyle="{StaticResource MathStyle}"
 41: 	        ComputerStyle="{StaticResource ComputerStyle}"/>
 42:     </Window.Resources>
 43:     <Grid>
 44:         <ListBox Name="list" Margin="5" 
 45:                  ItemContainerStyleSelector="{StaticResource myTStyleSelectorObj}">
 46:             <ListBox.ItemTemplate>
 47:                 <DataTemplate>
 48:                     <TextBlock Text="{Binding Path=Subject}"/>
 49:                 </DataTemplate>
 50:             </ListBox.ItemTemplate>
 51:         </ListBox>
 52:     </Grid>
 53: </Window>
 54: 

 

And here is complete C# code of our program.

 

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.Windows;
  6: using System.Windows.Controls;
  7: using System.Windows.Data;
  8: using System.Windows.Documents;
  9: using System.Windows.Input;
 10: using System.Windows.Media;
 11: using System.Windows.Media.Imaging;
 12: using System.Windows.Navigation;
 13: using System.Windows.Shapes;
 14: 
 15: namespace WpfControlTemplate
 16: {
 17:     /// <summary>
 18:     /// Interaction logic for Window1.xaml
 19:     /// </summary>
 20:     public partial class Window1 : Window
 21:     {
 22:         public Window1()
 23:         {
 24:             List<Student> subjects = new List<Student>();
 25: 
 26:             subjects.Add(new Student(100, "Linear Algebra"));
 27:             subjects.Add(new Student(200, "Data Structure"));
 28:             subjects.Add(new Student(200, "Software Engineering"));
 29:             subjects.Add(new Student(100, "Differential Equation"));
 30:             subjects.Add(new Student(100, "Complex Analysis"));
 31:             subjects.Add(new Student(200, "Database"));
 32:             subjects.Add(new Student(100, "Number Theory"));
 33: 
 34:             InitializeComponent();
 35: 
 36:             list.ItemsSource = subjects;
 37:         }
 38:     }
 39: 
 40:     public class MyStyleSelector : StyleSelector
 41:     {
 42:         public Style MathStyle
 43:         { get; set; }
 44: 
 45:         public Style ComputerStyle
 46:         { get; set; }
 47: 
 48:         public override Style SelectStyle(object item, DependencyObject container)
 49:         {
 50:             Student student = item as Student;
 51: 
 52:             if (student != null)
 53:             {
 54:                 if (student.Department == 100)
 55:                     return MathStyle;
 56: 
 57:                 if (student.Department == 200)
 58:                     return ComputerStyle;
 59:             }
 60:             return base.SelectStyle(item, container);
 61:         }
 62:     }
 63: 
 64:     public class Student
 65:     {
 66:         public Student(int department, String subject)
 67:         {
 68:             Department = department;
 69:             Subject = subject;
 70:         }
 71: 
 72:         public int Department
 73:         { get; set; }
 74: 
 75:         public String Subject
 76:         { get; set; }
 77:     }
 78: }
 79: 

 

Our program display a list box, where all the math subject display in ellipse with light blue background color and all math subject display in rectangle with wheat background color. This is the output of our program.

ControlTemplateConditionallyOutput

Advertisements

Responses

  1. Hi,

    I’m using an Hierarchical grid as defined here http://blogs.microsoft.co.il/blogs/davids/archive/2010/04/17/hierarchical-grid-with-wpf.aspx. This is basically a TreeView with columns.
    I wanted to know if it is possible to insert into the columns of this tree view a Control (ComboBox, TextBox, DatePicker) that is defined in my Info class (treeViewItem).

    If you can help it would be appreciated.

    Best Regards,

    Alexandre

    • What i understand by going through that article is that it is possible. Using TextBox and DatePicker is almost similer to using TextBlock, but for using ComboBox, ListBox, ItemControl etc, we need a list of data not just one content data. I will probably try my hand on it and post an article here.

      Thanks to visit my blog.

      Regards
      Zeeshan Amjad


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: