In previous article I described a how to create a SplitContainer control for WPF. I'm using this control (actually it is a custom panel) to build the next version of AvalonDock. If you downloaded the first version you have surely experienced some bugs, like those in MeasureOverride functions that returns PosInfinity if an infinity size is passed to it. I fixed these bugs but also I added some new interesting features.
SpliSize property is now of type GridLength instead of a simple double type. So one can specify three types of length for each FrameworkElement object contained into the split container: Absolute values, Proportional values and Auto values.
Why this change? In this way is possible to build GUI like you can see in Visual Studio or SharpDevelop. For example arrange Visual Studio like in the following figure:
Now if you resize the main window you can notice that the two panes attached to left/right borders maintain their widths vice ersa document panes are resized in order to occupy the remain space available for the window.
If you would to recreate an interface like that in WPF you should use a Grid panel. You should add 4 column definitions, setting first and last column widths with an absolute size (ex. GridLength(100)) and the second and third columns with a proportional width (ex. GridLength(1.0, GridUnit.Star).
Using the new version of SplitContainer panel you can specify the same GridLenght values for the internal controls and it will correctly manage them during resize operations. Also if you move splitters that are automatically created between two consecutive child controls, grid length values of all children are computed automatically by the panel.
To show how this process works, I created a small test application composed of five textblocks whose text contents are bound to the respective SplitSize attached property value. In the following figures you can see how it appears:
Moving splitters you can notice how SplitSize values change. What at first glance appeared an easy task, I discovered to be not so trivial and led me to build a complicated algorithm that you can find in methods like (Resize() and Measure/ArrangeOverride() ). Maybe you can find an easier way to accomplish that.
I also wanted to manage correctly the MinWidth/MinHeight properties of the children controls. Setting these values can be very useful when a pane must not be resized under a specific value.
Following is the snippet code that I use to test the splitcontainer:
<Window x:Class="SplitContainer.TestApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SplitContainer.TestApp"
xmlns:yd="clr-namespace:SplitContainer.YouDev.Controls;assembly=SplitContainer"
Title="Window1" Height="300" Width="500">
<Window.Resources>
<local:BoolToOrientationConverter x:Key="boolToOrientationConnverter"/>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Text" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(yd:SplitContainer.SplitSize)}"/>
</Style>
</Window.Resources>
<DockPanel>
<CheckBox x:Name="chkOrientation" Content="Horizontal/Vertical orientation" IsChecked="True" DockPanel.Dock="Bottom"/>
<yd:SplitContainer ResizeOrientation="{Binding Path=IsChecked, ElementName=chkOrientation, Converter = {StaticResource boolToOrientationConnverter}}">
<TextBlock />
<TextBlock yd:SplitContainer.SplitSize="100" ></TextBlock>
<TextBlock ></TextBlock>
<TextBlock yd:SplitContainer.SplitSize="100"></TextBlock>
<TextBlock ></TextBlock>
</yd:SplitContainer>
</DockPanel>
</Window>
Here you can download the code for the WPF SplitContainer control:
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5