tags:

views:

55

answers:

2

I have two expanders, side by side. I want only one to be expanded at a time. So if one is expanded, and the user expands the other, I want the first one to collapse. The user can have both collapsed, and both collapsed is the starting state.

As can be seen in the code, I have included the "Header" property as a test, and it works as expected, but the IsExpanded property is not working.

<Expander x:Name="emailExpander">
  <Expander.Style>
    <Style TargetType="Expander">
      <Setter Property="IsExpanded" Value="False"/>
      <Setter Property="Header" Value="Email"/>
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsExpanded,ElementName=customerExpander}" Value="True">
          <Setter Property="IsExpanded" Value="False"/>
          <Setter Property="Header" Value="other expanded"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Expander.Style>      
</Expander>
A: 

I found the answer in this post: http://stackoverflow.com/questions/1565932/wpf-expanders-triggers

Use BoolInverterConverter in the answer above and here is the code snippets for your case

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:BoolInverterConverter x:Key="bic"/>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Expander x:Name="emailExpander" IsExpanded="{Binding ElementName=customerExpander, Converter={StaticResource bic}, Path=IsExpanded}">
        <Expander.Style>
            <Style TargetType="Expander">
                <Setter Property="Header" Value="Email"/>
            </Style>
        </Expander.Style>
        <StackPanel Margin="10,4,0,0">
            <CheckBox Margin="4" Content="Email 1" />
            <CheckBox Margin="4" Content="Email 2" />
            <CheckBox Margin="4" Content="Email 3" />
        </StackPanel>
    </Expander>
    <Expander x:Name="customerExpander" Grid.Column="1"> 
        <Expander.Style>
            <Style TargetType="Expander">
                <Setter Property="Header" Value="Customer"/>
            </Style>
        </Expander.Style>
        <StackPanel Margin="10,4,0,0">
            <CheckBox Margin="4" Content="Customer 1" />
            <CheckBox Margin="4" Content="Customer 2" />
            <CheckBox Margin="4" Content="Customer 3" />
        </StackPanel>
    </Expander>
</Grid>

arinto
I thought of doing it this way, but feared a circular dependency. I thought the two expanders would just keep changing each other's expanded property ad infinitum?
Ok. I just tested that out, and as expected, and with a nice touch of irony, I got a stackoverflow exception :-)
Note that the second expander (in this case customerExpander) doesn't have binding definition of IsExpanded. Only the first expander (in this case emailExpander) has IsExpanded binding definition <<IsExpanded="{Binding ....}">>
arinto
anyway, found bug on my solution. It can't handle both expander in collapsed state :(
arinto
A: 

What you're better off doing is use an accordion control released in the WPF Toolkit V2. Very handy and no "Stack Overflow" exceptions. =)

Tri Q