4

I have 2 expanders inside a dockPanel, i need to fill all the height available inside de dockPanel when a expander is opened and if both of them are open, i need each expander to take the half of the available height so they can fill all the space. Here is my code:

<DockPanel Background="Black">
                    <Expander Name="articlesExpander" Template="{StaticResource ExpanderHeaderImage}" DockPanel.Dock="Top">
                        <Grid Name="articlesGridExpander" ShowGridLines="True" Background="#FFEC0000">
                            <TextBlock>Hello</TextBlock>
                        </Grid>
                    </Expander>
                    <Expander Name="turneroExpander" Template="{StaticResource ExpanderHeaderImage}" DockPanel.Dock="Bottom">
                        <Grid Name="turneroGridExpander" ShowGridLines="True" Height="{Binding ElementName=DummyExpanderHeight, Path=Height}" Background="#FF0AE400">
                            <TextBlock>Bye</TextBlock>
                        </Grid>
                    </Expander>
                </DockPanel>

Here i describe the 3 possible states of the expanders:

1) the first expander is open and the second is closed. As you can see the first expander does not take all the avialble height: enter image description here

2) The second expander is open and the first expander is closed. This is the right behaviour i would like to have with both expanders: enter image description here

3) Both expanders are open. I need them to take half and a half height: enter image description here

How can i achieve the right behaviour of the expanders?

Fernando Santiago
  • 2,128
  • 10
  • 44
  • 75

1 Answers1

9

You can achieve what you want using pure XAML if using a Grid instead of DockPanel. I don't see the purpose of using DockPanel in this case. Otherwise you need code behind (some Converter) to resize the Expanders correctly.

The idea here is we need a Grid having 2 rows, when the contained Expander is collapsed, the row's Height should be Auto, otherwise the row's Height should be *. When the 2 Expanders are expanded, both the rows have Height of * and each one will share half the whole Height of the Grid:

<Grid Background="Black">
      <Grid.Resources>
         <Style TargetType="RowDefinition">
             <Setter Property="Height" Value="Auto"/>
             <Style.Triggers>
                 <DataTrigger Binding="{Binding Tag.IsExpanded, RelativeSource={RelativeSource Self}}" 
                              Value="True">
                     <Setter Property="Height" Value="*"/>
                 </DataTrigger>
             </Style.Triggers>
         </Style>
      </Grid.Resources>
      <Grid.RowDefinitions>
         <RowDefinition Tag="{Binding ElementName=articlesExpander}"/>
         <RowDefinition Tag="{Binding ElementName=turneroExpander}"/>
      </Grid.RowDefinitions>
      <Expander Name="articlesExpander" Template="{StaticResource ExpanderHeaderImage}">
            <Grid Name="articlesGridExpander" ShowGridLines="True" Background="#FFEC0000">
              <TextBlock>Hello</TextBlock>
            </Grid>
      </Expander>
      <Expander Name="turneroExpander" Template="{StaticResource ExpanderHeaderImage}" Grid.Row="1">
            <Grid Name="turneroGridExpander" ShowGridLines="True" Height="{Binding ElementName=DummyExpanderHeight, Path=Height}" Background="#FF0AE400">
               <TextBlock>Bye</TextBlock>
            </Grid>
      </Expander>
 </Grid>
King King
  • 61,710
  • 16
  • 105
  • 130
  • This did not work for me as written, and I could not figure out why, but it led me to a working solution. I changed the DataTrigger binding to `{Binding IsExpanded, ElementName=articlesExpander}` and got rid of the RowDefinition Tag binding. (Fortunately I only have one expander I needed to apply it to, so I did not need a generic style) – Benjamin Herreid Mar 25 '16 at 21:53
  • 1
    For those with multiple expanders, the answer provided works as written if you change the DataTrigger binding to `"{Binding Tag.IsExpanded, RelativeSource={RelativeSource Self}}"` – McFixit Mar 28 '16 at 19:11
  • @McFixit thanks for your comment, maybe that was what missing in my answer making the OP not have it working. I'm sure I tried a working code, maybe it was just some how missing when I posted the answer here. – King King Mar 29 '16 at 10:12