using System.Windows; using System.Windows.Controls; namespace WpfApplication17 { partial class Window1 { GridLength[] starHeight; public Window1() { InitializeComponent(); starHeight = new GridLength[expanderGrid.RowDefinitions.Count]; starHeight[0] = expanderGrid.RowDefinitions[0].Height; starHeight[2] = expanderGrid.RowDefinitions[2].Height; ExpandedOrCollapsed(topExpander); ExpandedOrCollapsed(bottomExpander); // InitializeComponent calls topExpander.Expanded // while bottomExpander is null, if we hook this up in the xaml topExpander.Expanded += ExpandedOrCollapsed; topExpander.Collapsed += ExpandedOrCollapsed; bottomExpander.Expanded += ExpandedOrCollapsed; bottomExpander.Collapsed += ExpandedOrCollapsed; } void ExpandedOrCollapsed(object sender, RoutedEventArgs e) { ExpandedOrCollapsed(sender as Expander); } void ExpandedOrCollapsed(Expander expander) { var rowIndex = Grid.GetRow(expander); var row = expanderGrid.RowDefinitions[rowIndex]; if (expander.IsExpanded) { row.Height = starHeight[rowIndex]; row.MinHeight = 50; } else { starHeight[rowIndex] = row.Height; row.Height = GridLength.Auto; row.MinHeight = 0; } var bothExpanded = topExpander.IsExpanded && bottomExpander.IsExpanded; splitter.Visibility = bothExpanded ? Visibility.Visible : Visibility.Collapsed; } } }
<Window x:Class="WpfApplication17.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <!-- main grid --> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid Name="expanderGrid"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <Expander Name="topExpander" Header="Top expander" IsExpanded="True"> <Label Content="Top expander content" Background="AntiqueWhite"/> </Expander> <GridSplitter Name="splitter" ResizeDirection="Rows" HorizontalAlignment="Stretch" Grid.Row="1" Height="5" Background="LightBlue"/> <Expander Name="bottomExpander" Header="Bottom expander" Grid.Row="2" IsExpanded="True"> <Label Content="Bottom expander content" Background="LightGreen"/> </Expander> </Grid> <Label Content="Workarea" Grid.Column="1" Background="LightYellow"/> </Grid> </Window>
Very helpful post!
ReplyDeleteTo let the minimum expander height match the header height make the following modifications (assuming that topExpander is expanded and bottomExpander is not expanded by default):
1) add a field to the Window1 class: "double minHeight = 0;"
2) change "row.MinHeight = 50;" to "row.MinHeight = minHeight;" in the second ExpandedOrCollapsed function
3) add the following function:
void CalculateMinHeight(object sender, RoutedEventArgs e) {
minHeight = bottomExpander.ActualHeight;
expanderGrid.RowDefinitions[0].MinHeight = minHeight;
expanderGrid.RowDefinitions[2].MinHeight = minHeight;
bottomExpander.Expanded -= CalculateMinHeight;
}
4) add "bottomExpander.Expanded += CalculateMinHeight;" to the Window1 constructor
So thanks for your helpfully post! I added some lines your ExpandedOrCollapsed event for my work:
ReplyDeletevoid ExpandedOrCollapsed(object sender, RoutedEventArgs e)
{
Expander expander = sender as Expander;
foreach (var item in expanderGrid.Children)
{
if (item.GetType() == typeof(Expander))
{
Expander expItem = item as Expander;
expItem.Expanded -= ExpandedOrCollapsed;
expItem.Collapsed -= ExpandedOrCollapsed;
bool isExpanded = (expItem == expander && expItem.IsExpanded);
expItem.IsExpanded = isExpanded;
expItem.Expanded += ExpandedOrCollapsed;
expItem.Collapsed += ExpandedOrCollapsed;
}
}
ExpandedOrCollapsed(sender as Expander);
}
Very helpful piece. With help of your codes I created a collapsible Grid column which was a daunting task otherwise.
ReplyDeleteThanks !
Nice work! Very elegant & simple.
ReplyDeleteThanks!
Works like a charm, thanks a ton!
ReplyDelete