How to set MaxWidth column table depending on window or screen size in XAML

I have a 3 column grid in a window with a GridSplitter in the first column. I want to set the MaxWidth of the first column to a third of the parent window or the Width (or ActualWidth ) page, and I would rather do it in XAML if possible.

This is an example of XAML that can be played in XamlPad (or similar) that shows what I am doing.

 <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid> <Grid.ColumnDefinitions> <ColumnDefinition x:Name="Column1" Width="200"/> <ColumnDefinition x:Name="Column2" MinWidth="50" /> <ColumnDefinition x:Name="Column3" Width="{ Binding ElementName=Column1, Path=Width }"/> </Grid.ColumnDefinitions> <Label Grid.Column="0" Background="Green" /> <GridSplitter Grid.Column="0" Width="5" /> <Label Grid.Column="1" Background="Yellow" /> <Label Grid.Column="2" Background="Red" /> </Grid> </Page> 

As you can see, the width of the right column is tied to the width of the first column, so when you move the left column using a separator, the right column does the same :) If you move the left column to the right, it will eventually slide halfway through the page / windows and to the right side of the window, pushing columns 2 and 3 away.

I want to prevent this by setting MaxWidth of column 1 to a third of the width of the window (or something like that). I can do this in code quite easily, but how to do it in "only XAML"?

EDIT: David Schmitt suggested using SharedSizeGroup instead of binding, which is a great suggestion. My sample code would look like this:

 <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid IsSharedSizeScope="True"> <Grid.ColumnDefinitions> <ColumnDefinition x:Name="Column1" SharedSizeGroup="ColWidth" Width="40"/> <ColumnDefinition x:Name="Column2" MinWidth="50" Width="*" /> <ColumnDefinition x:Name="Column3" SharedSizeGroup="ColWidth"/> </Grid.ColumnDefinitions> <Label Grid.Column="0" Background="Green" /> <GridSplitter Grid.Column="0" Width="5" /> <Label Grid.Column="1" Background="Yellow" /> <Label Grid.Column="2" Background="Red" /> </Grid> </Page> 
+7
width wpf xaml actualwidth
source share
2 answers

I think the XAML-only approach is a little more helpful, but here is a way to do it.

 <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <!-- This contains our real grid, and a reference grid for binding the layout--> <Grid x:Name="Container"> <!-- hidden because it behind the grid below --> <Grid x:Name="LayoutReference"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <!-- We need the border, because the column doesn't have an ActualWidth --> <Border x:Name="ReferenceBorder" Background="Black" /> <Border Background="White" Grid.Column="1" /> <Border Background="Black" Grid.Column="2" /> </Grid> <!-- I made this transparent, so we can see the reference --> <Grid Opacity="0.9"> <Grid.ColumnDefinitions> <ColumnDefinition x:Name="Column1" MaxWidth="{Binding ElementName=ReferenceBorder,Path=ActualWidth}"/> <ColumnDefinition x:Name="Column2" MinWidth="50" /> <ColumnDefinition x:Name="Column3" Width="{ Binding ElementName=Column1, Path=Width }"/> </Grid.ColumnDefinitions> <Label Grid.Column="0" Background="Green"/> <GridSplitter Grid.Column="0" Width="5" /> <Label Grid.Column="1" Background="Yellow" /> <Label Grid.Column="2" Background="Red" /> </Grid> </Grid> </Page> 
+7
source share

Too lazy to write yourself, but you should be able to use a math converter and snap to the width of your parent windows (by name or by searching for RelativeSource ancestors).

 //I know I borrowed this from someone, sorry I forgot to add a comment from whom public class ScaledValueConverter : IValueConverter { public Object Convert(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture) { Double scalingFactor = 0; if (parameter != null) { Double.TryParse((String)(parameter), out scalingFactor); } if (scalingFactor == 0.0d) { return Double.NaN; } return (Double)value * scalingFactor; } public Object ConvertBack(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture) { throw new Exception("The method or operation is not implemented."); } } 
0
source share

All Articles