Naveen's Weblog

Bridge to future

Posts Tagged ‘XAML’

Data Triggers and Usage in XAML

Posted by codingsense on November 25, 2009

Hi,

DataTrigger represents a trigger that applies property values or performs actions when the bound data meets a specified condition.

In this sample we will explore how this property can be utilized on how we need it to behave. In this sample I will concentrate on Style Triggers and apply them on the datagrid, in similar fashion it can be applied to any of the container control.

Till now I have been using Data Triggers in many of the places in my project. Combining all the solutions I have made a sample in which i will be describing all the types of usages of Data Triggers.

Let us imagine a collection of Fathers which hold FirstName of fathers. Each father has a kids collection where all his kids names are stored.
The collection are displayed in a datagrid and the rows are displayed using a Listview and a gridview.

<my:DataGrid AutoGenerateColumns="False" Margin="28,39,33,21" Name="dataGrid1">············
<my:DataGrid.RowDetailsTemplate>················
<DataTemplate>····················
<ListView Name="Kids" ItemsSource="{Binding Kids}">························
<ListView.View>····························
<GridView>································
<GridViewColumn  Header="Kids" DisplayMemberBinding="{Binding Name}"/>····························
</GridView>························
</ListView.View>····················
</ListView>················
</DataTemplate>············
</my:DataGrid.RowDetailsTemplate>············
<my:DataGrid.Columns>················
<my:DataGridTextColumn Header="Father Name" Binding="{Binding FirstName}"/>············
</my:DataGrid.Columns>········
</my:DataGrid>

Now lets create some scenarios in our project in the format the details are to be displayed
Scenario1: Make the families background red where there are no kids
Scenario 2: Hide the families where the name of the father is less than 8 chars
Scenario 3: Make the font bold where the fathers name is greater than 8 chars and there are 2 kids

Download Source Code – 423Kb

Make the families background red where there are no kids
Binding is very flexible in WPF you can easily bind to any of the properties available in the class. Like in this scenario we need to check if the kids count in the family is 0. For this we need to declare a style and bind our RowStyle of the grid to the defined style. Lets work on it.
Lets declare a style and name it as CheckKids and check for the kids.count condition for 0.

········
<Style x:Key="CheckKids" TargetType="{x:Type my:DataGridRow}">············
<Style.Triggers>················
<DataTrigger Binding="{Binding Kids.Count}" Value="0">····················
<Setter Property="Background" Value="Red"/>················
</DataTrigger>············
</Style.Triggers>········
</Style>

In the collection Mr.Ramiayaa has no kids so background of his row is made red.

Hide the families where the name of the father is less than 8 chars
Now comes the challange how will you check fatherName < 8 in XAML. Pretty tricky right. Here is a simple method to be followed. What if we have another property in our class which returns true or false by checking the fathername.length. It will help us to acheive our goal.

Lets Declare a property in Father class and name it as IsLengthLessThanEight, which will return if the father name is less than 8 char or not. It will look like

public bool IsLengthLessThanEight
{
get { return (FirstName.Length < 8); }
}

By this we can be very sure that we can write our own properties and bind it to make anything possible.
Now lets declare the style and name it FatherNameLessEightChar and bind it to our declared property IsLengthLessThanEight
and check the desired condition.

········
<Style x:Key="FatherNameLessEightChar" TargetType="{x:Type my:DataGridRow}">············
<Style.Triggers>················
<DataTrigger Binding="{Binding IsLengthLessThanEight}" Value="True">····················
<Setter Property="Visibility" Value="Hidden"/>················
</DataTrigger>············
</Style.Triggers>········
</Style>

In the collection we have only one father who has the name less than 8 that is Mr.Rocky that name is to be hidden.


Make the font bold where the fathers name is greater than 8 chars and there are 2 kids
Here comes the next challange how will we check more than one condition in XAML. Is it possible or should we declare another property and check 2 conditions in our class. For this we have MultiDataTrigger which will help us to check multiple conditions in XAML and set property accordingly. Cool.
Lets declare a style and name it CheckNameAndKidsCount and use the MultiDataTrigger.

<Style x:Key="CheckNameAndKidsCount" TargetType="{x:Type my:DataGridRow}">············
<Style.Triggers>················
<MultiDataTrigger>····················
<MultiDataTrigger.Conditions>························
<Condition Binding="{Binding IsLengthLessThanEight}" Value="False"/>························
<Condition Binding="{Binding Kids.Count}" Value="2"/>····················
</MultiDataTrigger.Conditions>····················
<Setter Property="FontWeight" Value="Bold"/>················
</MultiDataTrigger>············
</Style.Triggers>········
</Style>


Here we check both the conditions i.e First we check if father name is greater than 8 char with the help of the IsLengthLessThanEight that we have defined and next condition we check if the kids count is 2 or not. If both the conditions are satisfied then the font of the family is made bold.
In our collection we have Mr.Balasubramanyam whose name is greater than 8 char and has 2 childrens so his row should be made bold.

Wow all the scenarios have completed and we have got the desired output for all of them. Thanks to DataTrigger for simplifying the life. In this similar fashion we can declare style trigger and data trigger to make various styles depending on the data that is bound.

References :
http://msdn.microsoft.com/en-us/library/system.windows.datatrigger.aspx

Cheers :)
Naveen Prabhu

Posted in WPF | Tagged: , , | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.