WPF Databinding visibility of a control to your ViewModel / DataContext boolean value.

By dsandor at May 05, 2010 18:57
Filed Under: Programming, WPF

In many cases you will need to set the visibility of a control based on a value of a property of your ViewModel class.  There are several ways to accomplish this.  The most reusable manner of accomplishing this is to use a value converter to convert the boolean value to a Visibility enumerator.  It sounds complicated but it is super easy.

Note: Before I continue I would like to state that this is an example simplified in order to describe this concept.  The code in this example databinds the IsChecked property of a CheckBox to the view model then databinds that boolean property to the Visibility property of the Button control.  In XAML you can property bind the two controls but that is not what this example is about.  Instead of making this a long example with database calls and other complications I wanted to make this as simple and clear cut as can be.  So if you are looking to databind the property of one control to the property of another this is not the right article for you.

image

So to demonstrate the value converter we will DataBind the (bool) IsChecked property of the CheckBox to the (bool) IsButtonVisible property of the MainWindowViewModel class.  The Visibility property of the Button control is databound to the same (bool) IsButtonVisible property of the MainWindowViewModel class.

So the XAML for this Window looks like this:

 

<Window x:Class="ValueConverterExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ValueConverterExample.Local"
        Title="MainWindow" Height="218" Width="196">
    <Grid>
        <Grid.Resources>
            <local:BooleanVisibilityValueConverter x:Key="BoolToVisible" />
        </Grid.Resources>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="51,110,0,0"
          Name="button1" VerticalAlignment="Top" Width="75" 
          Visibility="{Binding Path=IsButtonVisible,Converter={StaticResource BoolToVisible}}" />
        <CheckBox Content="Is Button Visible?" Height="16" HorizontalAlignment="Left"
          Margin="36,56,0,0" Name="checkBox1" VerticalAlignment="Top" 
          IsChecked="{Binding IsButtonVisible}" />
    </Grid>
</Window>

Note there is a Grid.Resources section in the XAML.  This section is making available to the controls on the Grid the BooleanVisibilityValueConverter object and is naming it BoolToVisible.  This will allow any control on this Grid to use that value converter.  In order to do this, I had to include a namespace that I called local in the Window tag declaration.  This sets up a reference to the Namespace where the Value Converter class resides.

Next, in the Button control’s XAML you see that the Visibility Property is DataBound to the IsButtonVisible property of the DataContext.  Below is the code behind for this Window:

namespace ValueConverterExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        MainWindowViewModel viewModel = new MainWindowViewModel();

        public MainWindow()
        {
            this.DataContext = viewModel;
            InitializeComponent();
        }
    }
}

And the code for the MainWindowViewModel is located below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace ValueConverterExample.ViewModel
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;


        private bool _IsButtonVisible;
        public bool IsButtonVisible
        {
            get { return _IsButtonVisible; }
            set
            {
                _IsButtonVisible = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("IsButtonVisible"));
            }
        }

    }
}

As you can see the IsButtonVisible property which both the CheckBox and Button are databound is a boolean.  This is possible via the ValueConverter:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Globalization;
using System.Windows.Media;
using System.Windows;

namespace ValueConverterExample.Local
{
    public class BooleanVisibilityValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                if (((bool)value) == true)
                    return Visibility.Visible;
                else
                    return Visibility.Collapsed;
            }

            return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {

            throw new Exception("The method or operation is not implemented.");

        }


    }
}

This value converter code will accept a Boolean value in, and spit out a Visibility enum.  The magic happens in this databinding expression for the button control’s visibility property:

Visibility="{Binding Path=IsButtonVisible,Converter={StaticResource BoolToVisible}}"

Here we are setting the binding to the IsButtonVisible property of the DataContext.  In addition we are telling the DataBinder to use the converter named BoolToVisible.  Remember we gave our BooleanVisibilityValueConverter class a key name of BoolToVisible when we defined the Grid Resources.

Attached is a sample project.  I hope this helps someone!

Download Source Code: ValueConverterExample.zip

Comments

5/19/2010 3:12:49 AM #

Hello from Germany! May i quote a post a translated part of your blog with a link to you? I've tried to contact you for the topic David Sandor | WPF Databinding visibility of a control to your ViewModel / DataContext boolean value., but i got no answer, please reply when you have a moment, thanks, Gedicht

Gedicht United States |

Comments are closed