<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding GridPanelWidth, Mode=TwoWay}" />
<ColumnDefinition Width="4" />
<!--splitter itself is in this column-->
<ColumnDefinition x:Name="RightColumn" Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border
BorderBrush="Gray"
BorderThickness="1"
Grid.Column="0"
Grid.Row="0"
/>
<GridSplitter
Background="SteelBlue"
ResizeBehavior="PreviousAndNext"
ResizeDirection="Columns"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
ShowsPreview="False"
Grid.Column="1"
Grid.Row="0"
/>
<Border
BorderBrush="Gray"
BorderThickness="1"
Grid.Column="2"
Grid.Row="0"
/>
<StackPanel
Grid.Row="1"
Grid.ColumnSpan="3"
Grid.Column="0"
>
<TextBlock>
<Run>GridPanelWidth: </Run>
<Run Text="{Binding GridPanelWidth.Value, Mode=OneWay}" />
<Run Text="{Binding GridPanelWidth.GridUnitType, Mode=OneWay}" />
</TextBlock>
<TextBlock>
<Run>RightColumn.Width: </Run>
<Run Text="{Binding Width.Value, ElementName=RightColumn, Mode=OneWay}" />
<Run Text="{Binding Width.GridUnitType, ElementName=RightColumn, Mode=OneWay}" />
</TextBlock>
</StackPanel>
</Grid>
Screenshot 1:

Screenshot 2:

Screenshot 3:

Res ipsa loquitor, as far as I'm concerned, but just to be on the safe side:
Because the parent may be resized, the grid splitter changes the ratio between the two columns, while preserving the GridUnitType.Star
for each one so that when the parent is resized, the ratio will naturally remain constant. This preserves the intent of the initial Width values in the XAML.
Width.Value
for the left column turns out to be identical to the left Border's ActualWidth
, and the same holds true for the right column. You'll have to grab both and save the ratio.
Update
I find Grid
/GridSplitter
a bit overengineered for everyday use when all I want is Yet Another Navigation Pane, so I recently wrote a SplitterControl
that has two content properties and sets up the grid and splitter, with styling, in the template. I hadn't gotten around to making the split ratio persistent, so I did that just now.
What I did was rather painful because the control is configurable, and the code isn't all that great, but I can share if you're interested.
The business end is simple:
When a column resizes, set a flag to block recursion and
PaneRatio = _PART_ContentColumn.Width.Value / _PART_NavColumn.Width.Value;
When PaneRatio
changes, if it wasn't set by the column size change handler
_PART_NavColumn.Width = new GridLength(1, GridUnitType.Star);
_PART_ContentColumn.Width = new GridLength(PaneRatio, GridUnitType.Star);
In practice, the navigator/content columns can be swapped, or they can be rows instead. Both of those are done by switching templates on a HeaderedContentControl
that's a child of the split control template.