Posted by: Zeeshan Amjad | June 22, 2010

Conditionally hide controls from data template


I came across a question that how can we hide some control from the data template conditionally depends on the data. We can do this with the help of data trigger. We can apply trigger at two different places. One at window level so we will use that for only only those controls, which are inside the data template, but for others too. Or we use the data trigger property of data template and define trigger at data template level. Here we are going to see the first approach, i.e. define the data trigger at window level.

Suppose we have a class, that stores some information such as debugging information of a program. In addition that class also have one more field to display explanation of the first field. Here is a class of it.

public class ReasonInfo
{
    public ReasonInfo(String reason, String explanation)
    {
        Reason = reason;
        Explanation = explanation;
    }

    public String Reason
    { get; set; }

    public String Explanation
    { get; set; }
}

 

Now we define one style and define data trigger in that style. Here is XAML code of it.

<Style x:Key="debugStyle" TargetType="{x:Type TextBlock}">
	<Style.Triggers>
		<DataTrigger Binding="{Binding Path=Explanation}" Value="Hidden">
			<Setter Property="Visibility" Value="Hidden"/>
		</DataTrigger>
	</Style.Triggers>
</Style>

Here is the usage of this style in data template.

<DataTemplate>
	<StackPanel Orientation="Horizontal">
		<TextBlock Text="{Binding Path=Reason}" Width="55"/>
		<TextBlock Style="{StaticResource debugStyle}" Text="{Binding Path=Explanation}"/>                        
	</StackPanel>
</DataTemplate>

Now the second text box will automatically disappear when the value of that field is hidden. Here is complete C# code of the program.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace WpfDataTemplate
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        ObservableCollection<ReasonInfo> reasons = new ObservableCollection<ReasonInfo>();

        public Window1()
        {
            InitializeComponent();

            reasons.Add(new ReasonInfo("Reason 1", "Explanation of reason 1"));
            reasons.Add(new ReasonInfo("Reason 2", "Explanation of reason 2"));
            reasons.Add(new ReasonInfo("Reason 3", "Hidden"));
            reasons.Add(new ReasonInfo("Reason 4", "Explanation of reason 4"));

            DataContext = reasons;
        }
    }

    public class ReasonInfo
    {
        public ReasonInfo(String reason, String explanation)
        {
            Reason = reason;
            Explanation = explanation;
        }

        public String Reason
        { get; set; }

        public String Explanation
        { get; set; }
    }
}

 

And here is complete XAML code of the program.

<Window x:Class="WpfDataTemplate.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Data Template" Height="300" Width="300">
    <Window.Resources>
        <Style x:Key="debugStyle" TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Explanation}" Value="Hidden">
                    <Setter Property="Visibility" Value="Hidden"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=Reason}" Width="55"/>
                        <TextBlock Style="{StaticResource debugStyle}" Text="{Binding Path=Explanation}"/>                        
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

 

This is the output of the program.

DataTriggerDataTemplate


Responses

  1. […] just saw how to hide control conditionally using data trigger here. We can do the same thing by defining the data trigger in data template. Let’s take look at the […]

  2. Hi, thanks for this article, it’s very useful. I need help in particular specification on Data Template. There is an example: I have a next XAML code for presenting rectangles:

    and the next C# code in the .cs file:

    public partial class MainWindow : Window
    {
    public MainWindow()
    {
    InitializeComponent();

    base.DataContext = new Activity[]
    {
    new Activity
    {
    LeftPosition = 10,
    TopPosition = 0,
    StrokeBorder = “Blue”
    },
    new Activity
    {
    LeftPosition = 100,
    TopPosition = 100,
    StrokeBorder = “Black”
    },
    new Activity
    {
    LeftPosition = 200,
    TopPosition = 200,
    StrokeBorder = “Red”
    }
    };

    public class Activity
    {
    public double TopPosition { get; set; }
    public double LeftPosition { get; set; }
    public string StrokeBorder { get; set; }
    }

    I want that the ContentControl show a rectangle position on the Canvas control across to the attribute Canvas.Top=”{Binding TopPosition}” and Canvas.Left=”{Binding LeftPosition}”. That example show three rectangles, but non in the canvas position (specificate in C# code). Thanks you !

  3. this is the XAML code: <!–

    –>


Leave a comment

Categories