WPF Expander y Splitter trabajando juntos..
Bueno aqui dejo publicado la solucion de un problemita que recientemente tuve haciendo que funcionarian juntos un Expander y un splitter bueno la meta final era tener 2 expanders separados por 1 splitter y que cada expander contuviera algun tipo de grids o incluso una vista con este aproach ya se puede jugar con lo que uno quiera poner en cada region,
Yo anduve buscando algo similar y no pude encontrar mucho al respecto asi que aqui dejo mi solucion y espero que a alguien pueda servirle..
Aqui tenemos el XAML con el codigo que contiene al expander y al splitter o mas bien dos expander conteniendo un grid cada uno separados por un splitter..
<window x:Class="ExpanderAndSplitter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" x:Name="MainWdw">
<grid x:Name="MainContainer" Loaded="MainContainer_Loaded" Margin="5,5,5,5" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" Background="Transparent">
</grid><grid .ColumnDefinitions>
<columndefinition Width="Auto" />
<columndefinition Width="Auto" />
<columndefinition Width="Auto" />
<columndefinition Width="*" />
<columndefinition Width="Auto" />
</grid>
<grid .RowDefinitions>
<rowdefinition Height="Auto"/>
<rowdefinition Height="*"/>
</grid>
<label x:Name="DummyLabel" Content="Dummy Label" />
<combobox x:Name="DummyComboBox" Grid.Column="1" MinWidth="100"
Margin="0,0,5,0"/>
<button Grid.Column="2" Width="100" Content="Dummy Button" />
<label x:Name="Label" Content="Dummy Label 2" Grid.Column="4" HorizontalAlignment="Right" />
<grid Grid.Row="1" Grid.ColumnSpan="5"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent">
</grid><grid .ColumnDefinitions>
<columndefinition />
</grid>
<grid .RowDefinitions>
<rowdefinition x:Name="MasterRow" Height="{Binding MasterRowHeight, Mode=TwoWay}" />
<rowdefinition x:Name="SplitterRow" Height="{Binding SplitterRowHeight, Mode=TwoWay}" />
<rowdefinition x:Name="DetailRow" Height="{Binding DetailRowHeight, Mode=TwoWay}" />
</grid>
<expander x:Name="MasterExpander" IsExpanded="True"
BorderBrush="Gray" Margin="0,5,0,0"
BorderThickness="1" IsEnabled="True"
ExpandDirection="Down" Background="Transparent"
Expanded="MasterExpander_Expanded"
Collapsed="MasterExpander_Collapsed" >
</expander><expander .Header>
<textblock FontWeight="Bold" Text="Master Region" />
</expander>
<grid Background="Transparent">
</grid><grid .ColumnDefinitions>
<columndefinition Width="*" />
</grid>
<grid .RowDefinitions>
<rowdefinition Height="*"/>
</grid>
<datagrid x:Name="MasterGrid"
Loaded="MasterGrid_Loaded"
AutoGenerateColumns="True"
CanUserDeleteRows="False"
ColumnWidth="*"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<gridsplitter Grid.Row="1" Background="Gray"
BorderThickness="1,1,1,1" Width="Auto" HorizontalAlignment="Stretch"
Height="6" VerticalContentAlignment="Top"
Padding="0,0,0,0" Margin="5,0,5,0" VerticalAlignment="Center"/>
<expander x:Name="DetailExpander" Grid.Row="2" Margin="0,5,0,0"
BorderBrush="Gray" BorderThickness="1" IsEnabled="True"
ExpandDirection="Down" Background="Transparent"
Expanded="DetailExpander_Expanded"
Collapsed="DetailExpander_Collapsed" >
</expander><expander .Header>
<textblock FontWeight="Bold" Text="Detail Region" />
</expander>
<grid Background="Transparent">
</grid><grid .ColumnDefinitions>
<columndefinition Width="*" />
</grid>
<grid .RowDefinitions>
<rowdefinition Height="*"/>
</grid>
<datagrid x:Name="DetailGrid"
Loaded="DetailGrid_Loaded"
AutoGenerateColumns="True"
CanUserDeleteRows="False"
ColumnWidth="*"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</window>
Y su respectivo code behind que se encarga de hacer las operaciones correspondientes de tamanio para que estos controles funcionen armoniosamente uno con el otro..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace ExpanderAndSplitter
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
#region Fields
private static double _oldMasterHeight = 1;
private static double _oldDetailHeight = 1;
#endregion // Fields
#region Properties
public GridLength MasterRowHeight
{
get { return (GridLength)GetValue(MasterRowHeightProperty); }
set { SetValue(MasterRowHeightProperty, value); }
}
// Using a DependencyProperty as the backing store for MasterRowHeight. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MasterRowHeightProperty =
DependencyProperty.Register("MasterRowHeight", typeof(GridLength), typeof(MainWindow), new UIPropertyMetadata(new GridLength(1, GridUnitType.Star)));
public GridLength SplitterRowHeight
{
get { return (GridLength)GetValue(SplitterRowHeightProperty); }
set { SetValue(SplitterRowHeightProperty, value); }
}
// Using a DependencyProperty as the backing store for SplitterRowHeight. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SplitterRowHeightProperty =
DependencyProperty.Register("SplitterRowHeight", typeof(GridLength), typeof(MainWindow), new UIPropertyMetadata(new GridLength(0)));
public GridLength DetailRowHeight
{
get { return (GridLength)GetValue(DetailRowHeightProperty); }
set { SetValue(DetailRowHeightProperty, value); }
}
// Using a DependencyProperty as the backing store for DetailRowHeight. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DetailRowHeightProperty =
DependencyProperty.Register("DetailRowHeight", typeof(GridLength), typeof(MainWindow), new UIPropertyMetadata(new GridLength(1, GridUnitType.Auto)));
public ObservableCollection<DummyItem> MasterItems
{
get;
set;
}
public ObservableCollection<DummyItem> DetailItems
{
get;
set;
}
#endregion // Properties
#region Constructors
public MainWindow()
{
InitializeComponent();
MasterItems = new ObservableCollection<DummyItem>();
DetailItems = new ObservableCollection<DummyItem>();
for (int i=0; i<1000; i++)
{
MasterItems.Add(new DummyItem("Master Dummy " + i.ToString(), i.ToString()));
DetailItems.Add(new DummyItem("Detail Dummy " + i.ToString(), i.ToString()));
}
}
#endregion // Constructors
#region Events
private void MasterExpander_Expanded(object sender, RoutedEventArgs e)
{
DoHandleExpandCollapse();
}
private void MasterExpander_Collapsed(object sender, RoutedEventArgs e)
{
if (DetailExpander.IsExpanded)
{
_oldMasterHeight = MasterRowHeight.Value;
_oldDetailHeight = DetailRowHeight.Value;
}
DoHandleExpandCollapse();
}
private void DetailExpander_Expanded(object sender, RoutedEventArgs e)
{
DoHandleExpandCollapse();
}
private void DetailExpander_Collapsed(object sender, RoutedEventArgs e)
{
if (MasterExpander.IsExpanded)
{
_oldMasterHeight = MasterRowHeight.Value;
_oldDetailHeight = DetailRowHeight.Value;
}
DoHandleExpandCollapse();
}
private void MasterGrid_Loaded(object sender, RoutedEventArgs e)
{
if (MasterGrid.ItemsSource == null)
MasterGrid.ItemsSource = MasterItems;
}
private void DetailGrid_Loaded(object sender, RoutedEventArgs e)
{
if (DetailGrid.ItemsSource == null)
DetailGrid.ItemsSource = DetailItems;
}
private void MainContainer_Loaded(object sender, RoutedEventArgs e)
{
MainContainer.DataContext = this;
}
#endregion // Events
#region Helpers
private void DoHandleExpandCollapse()
{
if (MasterExpander == null || DetailExpander == null)
return;
SplitterRowHeight = new GridLength(0);
if (MasterExpander.IsExpanded && DetailExpander.IsExpanded)
{
MasterRowHeight = new GridLength(_oldMasterHeight, GridUnitType.Star);
DetailRowHeight = new GridLength(_oldDetailHeight, GridUnitType.Star);
SplitterRowHeight = new GridLength(20);
return;
}
if (MasterExpander.IsExpanded)
MasterRowHeight = new GridLength(1, GridUnitType.Star);
else
MasterRowHeight = new GridLength(1, GridUnitType.Auto);
if (DetailExpander.IsExpanded)
DetailRowHeight = new GridLength(1, GridUnitType.Star);
else
DetailRowHeight = new GridLength(1, GridUnitType.Auto);
}
#endregion // Helpers
}
public class DummyItem
{
public DummyItem(string name, string id)
{
this.Name = name;
this.ID = id;
}
public string Name
{
get;
set;
}
public string ID
{
get;
set;
}
}
}
Al final asi es como luce la solucion:
La solucion ejemplo esta hecha con Visual Studio 2010 y el codigo fuente lo puedes bajar del siguiente link ExpanderAndSplitter.
Enjoy! ![]()
Yohan Rodriguez

En un intento por mejorar o morir tratando, gracias por tu visita!
