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.
This class define only one method name select style which returns style. Here is a class diagram of Style Selector.
Here is a class inherited by Data Template Selector.
1: public class MyStyleSelector : StyleSelector2: {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 : Window21: {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 : StyleSelector38: {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 Student67: {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 ID80: { 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.
[…] 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 […]
By: Apply Control Template Conditionally « Zeeshan Amjad's WPF Blog on February 3, 2010
at 10:42 pm
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.
By: Ajay on December 19, 2012
at 10:16 am
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.
By: Zeeshan Amjad on February 8, 2013
at 4:47 pm
what a bad formatting!
By: some Name on June 13, 2018
at 2:52 pm