Binding to a WPF ToggleButton's IsChecked state
Asked Answered
K

3

25

I would like to use a WPF ToggleButton to expand and collapse some controls in my application. How can I use XAML to accomplish this?

I'm thinking that I could somehow bind the Visibility attribute of some controls to the ToggleButton's IsChecked state, but I do not know how to do this.

Maybe I need to give my ToggleButton a Name, then bind using ElementName? Then I would need a ValueConverter for converting between a boolean value and a Visibility, correct? How could I make a generic ValueConverter for this purpose?

Knightly answered 7/10, 2009 at 21:10 Comment(1)
"How could I make a generic ValueConverter for this purpose?" You don't need to: it's already in the framework. Look for BooleanToVisibilityConverter.Ovule
E
45

You need to bind the Visibility through a converter:

<Window
  x:Class="WpfApplication1.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
  </Window.Resources>
  <StackPanel>
    <ToggleButton x:Name="toggleButton" Content="Toggle"/>
    <TextBlock
      Text="Some text"
      Visibility="{Binding IsChecked, ElementName=toggleButton, Converter={StaticResource BooleanToVisibilityConverter}}"/>
  </StackPanel>
</Window>

In Silverlight there is no BooleanToVisibilityConverter but it is easy to write your own with some added features:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication1 {

  public class BooleanToVisibilityConverter : IValueConverter {

    public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture) {
      if (targetType == typeof(Visibility)) {
        var visible = System.Convert.ToBoolean(value, culture);
        if (InvertVisibility)
          visible = !visible;
        return visible ? Visibility.Visible : Visibility.Collapsed;
      }
      throw new InvalidOperationException("Converter can only convert to value of type Visibility.");
    }

    public Object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture) {
      throw new InvalidOperationException("Converter cannot convert back.");
    }

    public Boolean InvertVisibility { get; set; }

  }

}

Now you can specify a converter that maps true to Collapsed and false to Visible:

<BooleanToVisibilityConverter
  x:Key="InverseBooleanToVisibilityConverter" InvertVisibility="True"/>
Ebersole answered 7/10, 2009 at 21:27 Comment(2)
I believe it should also be possible to use triggers in a similar manner, a la #251340Knightly
Think of the first simple and intuitive framework you can think of. It was probably not WPF.Axletree
O
8

Use the BooleanToVisibilityConverter:

<BooleanToVisibilityConverter x:Key="bvc" />
<TextBlock Visibility="{Binding IsChecked, ElementName=toggle, Converter={StaticResource bvc}}" />
Ovule answered 7/10, 2009 at 21:20 Comment(0)
E
0

Is there a reason why you aren't just using the Expander? It's based on the ToggleButton anyway.

Epicycle answered 7/10, 2009 at 21:12 Comment(2)
I am doing more than just expanding and collapsing--I am rearranging content. For example I'd like to set a StackPanel's Orientation and a TextBlock's TextWrapping and FontSize properties. I didn't specify this since I wanted to keep the question simple.Knightly
Fair enough :-) You should be able to bind with {binding elementname=mytoggle, propertyname=checked} or even use a trigger on the toggle to set the targets style.Epicycle

© 2022 - 2024 — McMap. All rights reserved.