Search code examples
windows-phone-7windows-phone-8textblock

How to Bind Visibility of Several Controls on a Page


At the click of a button, I would like to be able to toggle the visibility of several items on a page simultaneously. What would be the best possible solution for this? For instance, I have about 15 TextBlocks that need to be either Visible or Collapsed based on when a button is pressed.

EDIT

In my view in each of my TextBlocks I am placing

Visibility="{Binding TextBlockVisible, Converter={StaticResource BoolVisibilityConverter}}"

And my BoolVisibilityConverter class

public class BoolVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

so on a button click how can I get the Visibility of the TextBlocks to change? The following is not working

private void ChangeVisibility_Click(object sender, RoutedEventArgs e)
{
    TextBlockVisible = !TextBlockVisible;  //does not change Visibility of TextBlocks       
}

private bool textBlockVisible = true;

    public bool TextBlockVisible 
    {
        get
        {
            return textBlockVisible;
        }

        set
        {
            textBlockVisible = value;
            NotifyPropertyChanged("TextBlockVisible");
        }
    }

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(info));
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

and in App.xaml

 <converters:BoolVisibilityConverter x:Key="BoolVisibilityConverter"/>

Solution

  • When you configure a binding you have to specify the data source and the data property.

    In your example code, you specify the source property 'TextBlockVisible'

    Visibility='{ Binding TextBlockVisible ,
                  Converter={StaticResource BoolVisibilityConverter}}'
    
     <!-- No source set for binding -->
    

    but you don't indicate the source itself. When there is no source specified the binding framework looks at the DataContext property for the source. Your TextBlocks don't have the DataContext set, so the binding framework examines the DataContext property on each parent element (until it reaches phone:PhoneApplicationPage )

    As @Oleg points out, you haven't set the DataContext, which is why the binding is not working.

    Since the TextBlockVisible property is a member of your page class you need to set in the page constructor.

     public MainPage() {
        InitializeComponent();
        DataContext = this;  
      }
    

    FWIW, properties like TextBlockVisible are usually kept in a separate ViewModel class. Then your setup code would be:

    var vm = new ExampleViewModel();
    DataContext = vm;