WPF - Bind UserControl visibility to a property

38,839

Solution 1

I would recommend using a IValueConverter to accept your boolean, and return a member of Visibility enumeration.

Here is a good example of one: http://jeffhandley.com/archive/2008/10/27/binding-converters---visibilityconverter.aspx

The XAML would look like this:

First you define a resource for the converter (put this in a resource dictionary):

<local:BooleanToVisibilityConverter x:Key="myBoolToVisibilityConverter" />

And then change your template like this:

<ControlTemplate x:Key="ListViewControlTemplate1" TargetType="{x:Type ListView}">
    <Grid Visibility="{Binding IsLoading, Converter={StaticResource myBoolToVisibilityConverter}}">
        <local:ActivityIndicatorControl 
            HorizontalAlignment="Center" 
            Height="Auto" 
            Margin="0" 
            VerticalAlignment="Center"/>
    </Grid>
</ControlTemplate>

Solution 2

Use .NET's built in Converter

.NET 3 has a built in BooleanToVisibilityConverter.

(Note: May not be available on all platforms, ex: mobile)

First add it to your Resources

<UserControl.Resources>
    <BooleanToVisibilityConverter x:Key="bool2vis"></BooleanToVisibilityConverter>
</UserControl.Resources>

Then use it on an element

<Label Visibility="{Binding IsSomeProperty, Converter={StaticResource bool2vis}}" />

Inverting

How do I invert BooleanToVisibilityConverter?

If you want to invert the converter (ex: hide the element when your property is true), this answer has a custom implementation of IValueConverter that supports that via XAML

<Application.Resources>
    <app:BooleanToVisibilityConverter 
        x:Key="BooleanToVisibilityConverter" 
        True="Collapsed" 
        False="Visible" />
</Application.Resources>
Share:
38,839

Related videos on Youtube

Martin
Author by

Martin

JavaScript, Angular, Node. I hope that one day I will answer more questions than ask!

Updated on July 09, 2022

Comments

  • Martin
    Martin almost 2 years

    I have a ListView bound to ObservableCollection. Data are loaded from the internet and then added to collection. The download takes few seconds and I want to indicate user that the data is loading.

    I created an UserControl that indicates activity. I placed it inside of ControlTemplate.

    <ControlTemplate x:Key="ListViewControlTemplate1" TargetType="{x:Type ListView}">
        <Grid>
            <local:ActivityIndicatorControl 
                HorizontalAlignment="Center" 
                Height="Auto" 
                Margin="0" 
                VerticalAlignment="Center"/>
        </Grid>
    </ControlTemplate>
    

    I would like to bind Visibility of ActivityIndicatorControl to a property, let's say bool IsLoading and set it to Visible/Collapsed correspondingly.

    Thanks!

  • Martin
    Martin about 12 years
    Thanks, exactly what I was looking for! Also, does the UserControl inherit DataContext from Grid? Would it be possible to create the binding on the UserControl itself?
  • davisoa
    davisoa about 12 years
    Yes, the UserControl would have the same DataContext as the Grid. Because of this, you could put the visibility binding on the UserControl with no problem.
  • Kaitnieks
    Kaitnieks over 7 years
    A small note: change BooleanToVisibiltyConverter to BooleanToVisibilityConverter (add missing "i") and it looks like this: <BooleanToVisibilityConverter x:Key="myBoolToVisibilityConverter" />