Sunday 28 July 2013

WPF - Achieve same functionality using IValueConverter and Trigger

Sample Code for Download

WPF is quite flexible and powerful in nature. WPF provides variety of features that can be used to achieve the desired functionality easily. Let me  show an example where same functionality can be achieved using different ways. There are several such examples that we would come across while using WPF, I am sharing just one of them here.

Functionality we try to achieve is as follows

When Checkbox is in Checked state, show details panel

When Checkbox is in Unchecked state, hide details panel.

For this functionality, we use a Checkbox and a StackPanel containing details.

Output

     

Approach 1. Using IValueConverter

<Window x:Class="WPFMultipleOptions.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"></BooleanToVisibilityConverter>
</Window.Resources>
<StackPanel Orientation="Vertical" Margin="10">

<CheckBox Name="chkShowDetails" Content="Show Details - using Converter" Margin="0 10 0 0">
</CheckBox>

<StackPanel Name="spDetails" Margin="0 10 0 0" Visibility ="{Binding ElementName=chkShowDetails, Path=IsChecked, Converter={StaticResource ResourceKey=BoolToVisibilityConverter}}">
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="10" Padding="10">
<StackPanel Orientation="Vertical">
<TextBlock Text="Details Here"></TextBlock>
<TextBlock Text="Details Here"></TextBlock>
<TextBlock Text="Details Here"></TextBlock>
<TextBlock Text="Details Here"></TextBlock>
<TextBlock Text="Details Here"></TextBlock>
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
</Window>

In above code, we have used Element to Element binding. StackPanel Visibility property is bound to CheckBox IsChecked property.


But Visibility property is of type enum and expects one of these values: Visible, Hidden or Collapsed. While CheckBox IsChecked property returns True or False.


So we use built-in BooleanToVisibilityConverter that converts takes Boolean value as input and returns Visibility value as output.


Approach 2. Using Trigger


Now same functionality can also be achieved using triggers. Let’s see how.

<Window x:Class="MultipleOptions.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Vertical" Margin="10">

<CheckBox Name="chkShowDetailsUsingTrigger" Content="Show Details - using trigger" Margin="0 10 0 0">
</CheckBox>

<StackPanel Name="spDetailsUsingTrigger" Margin="0 10 0 0">
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="10" Padding="10">
<StackPanel Orientation="Vertical">
<TextBlock Text="Details Here"></TextBlock>
<TextBlock Text="Details Here"></TextBlock>
<TextBlock Text="Details Here"></TextBlock>
<TextBlock Text="Details Here"></TextBlock>
<TextBlock Text="Details Here"></TextBlock>
</StackPanel>
</Border>
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Visibility" Value="Hidden"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=chkShowDetailsUsingTrigger, Path=IsChecked}" Value="True">
<Setter Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>

</StackPanel>
</StackPanel>
</Window>

In above code, by default we have set visibility of StackPanel (details section) to false. Then we have added DataTrigger on StackPanel. DataTrigger Binding is set to CheckBox IsChecked property. If value is True then Setter gets executed and sets Visibility of StackPanel to true.