GridSplitter MinWidth with fixed size
gridsplitter, silverlight, silverlight-toolkit, wpf, xaml
Solution
The basic problem is that a grid splitter works by adjusting the width of the left column only and assumes the right column will star-size to fit the remaining space.
That means the problem you are trying to solve is actually "how do I limit the max width of the left column so that the right column does not get too small?". This is basically what your code sample is doing.
If you want a more portable solution, that you can implement in XAML, create a Silverlight behavior that can be applied to a grid (as shown below). It will attach to the parent grid's `SizeChanged` event and do pretty much exactly what your code snippet does, but being a behavior you can drag and drop them in Blend or attach them in XAML.
Here is a sample behavior I threw together for you as an example (based on your own code):
MinWidthSplitterBehavior.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
namespace GridSplitterMinWidth
{
public class MinWidthSplitterBehavior : Behavior<Grid>
{
public Grid ParentGrid { get; set; }
protected override void OnAttached()
{
base.OnAttached();
ParentGrid = this.AssociatedObject as Grid;
ParentGrid.SizeChanged += parent_SizeChanged;
}
void parent_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ParentGrid.ColumnDefinitions.Count == 3)
{
Double maxW = e.NewSize.Width - ParentGrid.ColumnDefinitions[2].MinWidth -
ParentGrid.ColumnDefinitions[1].ActualWidth;
ParentGrid.ColumnDefinitions[0].MaxWidth = maxW;
}
}
protected override void OnDetaching()
{
base.OnDetaching();
if (ParentGrid != null)
{
ParentGrid.SizeChanged -= parent_SizeChanged;
}
}
}
}
and use it like this:
<UserControl x:Class="GridSplitterMinWidthApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:GridSplitterMinWidth="clr-namespace:GridSplitterMinWidth"
xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" MinWidth="20" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" MinWidth="100" />
</Grid.ColumnDefinitions>
<interactivity:Interaction.Behaviors>
<GridSplitterMinWidth:MinWidthSplitterBehavior/>
</interactivity:Interaction.Behaviors>
<Rectangle Fill="Blue" />
<Controls:GridSplitter Grid.Column="1" Background="LightGray" HorizontalAlignment="Stretch">
</Controls:GridSplitter>
<Rectangle Fill="Yellow" Grid.Column="2" />
</Grid>
</Grid>
</UserControl>
Problem
I have a Grid with 2 columns separated by a GridSplitter using the following XAML code : ``` <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="100" MinWidth="20" /> <ColumnDefinition Width="10" /> <ColumnDefinition Width="*" MinWidth="100" /> </Grid.ColumnDefinitions> <Rectangle Fill="Blue" /> <GridSplitter Grid.Column="1" Background="LightGray" HorizontalAlignment="Stretch" /> <Rectangle Fill="Yellow" Grid.Column="2" /> </Grid> ``` Problem : The MinWidth of the Column on the right is ignored - I definitely need the first column Width to be "100px" when page loads, so It cannot be * sized. - I do not want to set a MaxWidth on the first column *I know that has been adressed before but it always suggest to set column size to * or set a maxWidth on the first column... I don't want that. Found a solution, but its UGLY! :p, anybody has a cleaner way to achieve what I want... CODELESS (if possible)? ``` private void Grid_SizeChanged(object sender, SizeChangedEventArgs e) { var g = (Grid)sender; Double maxW = e.NewSize.Width - g.ColumnDefinitions[2].MinWidth - g.ColumnDefinitions[1].ActualWidth; g.ColumnDefinitions[0].MaxWidth = maxW; } ```