Posted by: Zeeshan Amjad | January 1, 2010

Applying Style conditionally


We have studied how can we apply style. Now we are going to see how can we apply style conditionally. In other words apply different style depends on the value of the object.

In our example we are going to make three different styles for bad, average and good student. In this example we just change the its back ground color, but we can set different properties. Here is a XAML code to define three styles.

  1: <Style x:Key="Bad" TargetType="ListBoxItem">
  2: 	<Setter Property="Background">
  3: 		<Setter.Value>
  4: 			<LinearGradientBrush>
  5: 				<GradientStop Offset="0" Color="LightPink"/>
  6: 				<GradientStop Offset="1" Color="Red"/>
  7: 			</LinearGradientBrush>
  8: 		</Setter.Value>
  9: 	</Setter>
 10: </Style>
 11: <Style x:Key="Average" TargetType="ListBoxItem">
 12: 	<Setter Property="Background">
 13: 		<Setter.Value>
 14: 			<LinearGradientBrush>
 15: 				<GradientStop Offset="0" Color="LightYellow"/>
 16: 				<GradientStop Offset="1" Color="Wheat"/>
 17: 			</LinearGradientBrush>
 18: 		</Setter.Value>
 19: 	</Setter>
 20: </Style>
 21: <Style x:Key="Good" TargetType="ListBoxItem">
 22: 	<Setter Property="Background">
 23: 		<Setter.Value>
 24: 			<LinearGradientBrush>
 25: 				<GradientStop Offset="0" Color="LightGreen"/>
 26: 				<GradientStop Offset="1" Color="Green"/>
 27: 			</LinearGradientBrush>
 28: 		</Setter.Value>
 29: 	</Setter>
 30: </Style>
 31: 

Now we are going to inherit class from Style Selector. This class is inherited by object class directly. Here is a class hierarchy of Style Selector class.

StyleSelector_01

This class define only one method name select style which returns style. Here is a class diagram of Style Selector.

StyleSelector_02 

Here is a class inherited by Data Template Selector.

  1: public class MyStyleSelector : StyleSelector
  2: {
  3:     public Style BadStudentStyle
  4:     { get; set; }
  5: 
  6:     public Style AvgStudentStyle
  7:     { get; set; }
  8: 
  9:     public Style GoodStudentStyle
 10:     { get; set; }
 11: 
 12:     public override Style SelectStyle(object item, DependencyObject container)
 13:     {
 14:         Student student = item as Student;
 15: 
 16:         if (student != null)
 17:         {
 18:             if (student.Percentage < 50)
 19:                 return BadStudentStyle;
 20:             else if (student.Percentage >= 50 && student.Percentage < 80)
 21:                 return AvgStudentStyle;
 22:             else if (student.Percentage > 80)
 23:                 return GoodStudentStyle;
 24:         }
 25: 
 26:         return base.SelectStyle(item, container);
 27:     }
 28: }
 29: 

 

Now we are going to make object of this class in XAML. Here is a code to create object of this class in XAML.

  1: <local:MyStyleSelector x:Key="myTStyleSelectorObj" 
  2: 	BadStudentStyle="{StaticResource Bad}"
  3: 	AvgStudentStyle="{StaticResource Average}"
  4: 	GoodStudentStyle="{StaticResource Good}"/>
  5: 

ItemContainerStyleSelector is a property of ListBox class. In fact this property is inherted by ItemsControl class. Now we are using our new class object. Here is XAML code to use our new class object.

  1: <ListBox Name="list" Margin="5" HorizontalContentAlignment="Stretch"
  2: 		 ItemContainerStyleSelector="{StaticResource myTStyleSelectorObj}">
  3: 	<ListBox.ItemTemplate>
  4: 		<DataTemplate>
  5: 			<Border Margin="2" BorderBrush="Brown" BorderThickness="1" CornerRadius="5">
  6: 				<StackPanel Margin="2">
  7: 					<TextBlock Foreground="Black" Text="{Binding ID}"/>
  8: 					<TextBlock Foreground="Black" FontSize="16" Text="{Binding Name}"/>
  9: 					<TextBlock Foreground="Black" Text="{Binding Percentage}"/>
 10: 				</StackPanel>
 11: 			</Border>
 12: 		</DataTemplate>
 13: 	</ListBox.ItemTemplate>    
 14: </ListBox>
 15: 

Now if we are storing students information in the list box then it will select different style depends on the percentage of the student. Here is a complete XAML code of the project

  1: <Window x:Class="WpfConditionalStyle.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:WpfConditionalStyle"
  5:     Title="Conditional Style" Height="400" Width="400">
  6:     <Window.Resources>
  7:         <Style x:Key="Bad" TargetType="ListBoxItem">
  8:             <Setter Property="Background">
  9:                 <Setter.Value>
 10:                     <LinearGradientBrush>
 11:                         <GradientStop Offset="0" Color="LightPink"/>
 12:                         <GradientStop Offset="1" Color="Red"/>
 13:                     </LinearGradientBrush>
 14:                 </Setter.Value>
 15:             </Setter>
 16:         </Style>
 17:         <Style x:Key="Average" TargetType="ListBoxItem">
 18:             <Setter Property="Background">
 19:                 <Setter.Value>
 20:                     <LinearGradientBrush>
 21:                         <GradientStop Offset="0" Color="LightYellow"/>
 22:                         <GradientStop Offset="1" Color="Wheat"/>
 23:                     </LinearGradientBrush>
 24:                 </Setter.Value>
 25:             </Setter>
 26:         </Style>
 27:         <Style x:Key="Good" TargetType="ListBoxItem">
 28:             <Setter Property="Background">
 29:                 <Setter.Value>
 30:                     <LinearGradientBrush>
 31:                         <GradientStop Offset="0" Color="LightGreen"/>
 32:                         <GradientStop Offset="1" Color="Green"/>
 33:                     </LinearGradientBrush>
 34:                 </Setter.Value>
 35:             </Setter>
 36:         </Style>
 37:         <local:MyStyleSelector x:Key="myTStyleSelectorObj" 
 38:                                   BadStudentStyle="{StaticResource Bad}"
 39:                                   AvgStudentStyle="{StaticResource Average}"
 40:                                   GoodStudentStyle="{StaticResource Good}"/>
 41:     </Window.Resources>
 42:     <Grid>
 43:         <ListBox Name="list" Margin="5" HorizontalContentAlignment="Stretch"
 44:                  ItemContainerStyleSelector="{StaticResource myTStyleSelectorObj}">
 45:             <ListBox.ItemTemplate>
 46:                 <DataTemplate>
 47:                     <Border Margin="2" BorderBrush="Brown" BorderThickness="1" CornerRadius="5">
 48:                         <StackPanel Margin="2">
 49:                             <TextBlock Foreground="Black" Text="{Binding ID}"/>
 50:                             <TextBlock Foreground="Black" FontSize="16" Text="{Binding Name}"/>
 51:                             <TextBlock Foreground="Black" Text="{Binding Percentage}"/>
 52:                         </StackPanel>
 53:                     </Border>
 54:                 </DataTemplate>
 55:             </ListBox.ItemTemplate>    
 56:         </ListBox>
 57:     </Grid>
 58: </Window>
 59: 

 

and here is complete C# code of the project.

 

  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 WpfConditionalStyle
 16: {
 17:     /// <summary>
 18:     /// Interaction logic for Window1.xaml
 19:     /// </summary>
 20:     public partial class Window1 : Window
 21:     {
 22:         public Window1()
 23:         {
 24:             InitializeComponent();
 25: 
 26:             List<Student> students = new List<Student>();
 27: 
 28:             students.Add(new Student(10, "Smith", 82.7));
 29:             students.Add(new Student(14, "Jon", 62.3));
 30:             students.Add(new Student(17, "Bob", 46.6));
 31:             students.Add(new Student(26, "Alex", 75.1));
 32: 
 33:             list.ItemsSource = students;
 34:         }
 35:     }
 36: 
 37:     public class MyStyleSelector : StyleSelector
 38:     {
 39:         public Style BadStudentStyle
 40:         { get; set; }
 41: 
 42:         public Style AvgStudentStyle
 43:         { get; set; }
 44: 
 45:         public Style GoodStudentStyle
 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.Percentage < 50)
 55:                     return BadStudentStyle;
 56:                 else if (student.Percentage >= 50 && student.Percentage < 80)
 57:                     return AvgStudentStyle;
 58:                 else if (student.Percentage > 80)
 59:                     return GoodStudentStyle;
 60:             }
 61: 
 62:             return base.SelectStyle(item, container);
 63:         }
 64:     }
 65: 
 66:     public class Student
 67:     {
 68:         public Student()
 69:         {
 70:         }
 71: 
 72:         public Student(int id, String name, double percentage)
 73:         {
 74:             ID = id;
 75:             Name = name;
 76:             Percentage = percentage;
 77:         }
 78: 
 79:         public int ID
 80:         { get; set; }
 81: 
 82:         public String Name
 83:         { get; set; }
 84: 
 85:         public Double Percentage
 86:         { get; set; }
 87:     }
 88: }
 89: 

Here is the output of this program.

ConditionalStyleOutput


Responses

  1. […] 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 […]

  2. It is a great article. I could make it to work win rt environment too. Would like to see if it is possible to add some buttons that will change the background,etc.

    • Thanks Ajay to like it. I am sure we can do the same thing with button. I will probablly write a sample program to demonstrate this.

  3. what a bad formatting!


Leave a comment

Categories