Limit the maximum width of the Auto column in a WPF data grid

I have a standard WPF grid with two columns defined as:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" MinWidth="200" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    ...
</Grid>

I want to ensure that the second column is automatically set based on its contents, and the first column gets all the remaining space. However, I also want the first column to never have less than 200 pixels. The problem is that with this configuration, my auto column will be disabled, not changed.

I really want WPF to first assign 200 pixels to the first columns, then take all the remaining space and ask the contents of the second column to fit the size with the maximum size limit of the remaining width. If content requires less space, it should assign the remaining space to the first column (making it larger than 200 pixels).

Use case: The second column is an image with a fixed aspect ratio, so there is an optimal width for a given height. I also have a first column with some controls that should always be visible. If there is more free space than necessary, I would like to assign space for the first column instead of the second.

WPF Grid ?

+5
2

, , , , , 2 + 200 . , , :

<Grid Height="200"
      Width="600">
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"
                      MinWidth="200" />
    <ColumnDefinition Width="Auto" />
  </Grid.ColumnDefinitions>
  <Border Background="Blue"
          Grid.Column="0" />
  <Viewbox Grid.Column="1"
           Stretch="Uniform"
           MaxWidth="400">
    <Border Background="Yellow"
            BorderBrush="Red"
            BorderThickness="4"
            Height="200"
            Width="300" />
  </Viewbox>
</Grid>

<ColumnDefinition Width="Auto" MaxWidth="400"/>, maxwidth .

MaxWidth - 200, .

+1

, , , 2 . , , , 200 . .

2 : , , . , IMultiValueConverter. , :

public class AutoColumnConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        double imageWidth = values.OfType<double>().FirstOrDefault();
        double gridWidth = values.OfType<double>().ElementAtOrDefault(1);
        int minWidth = System.Convert.ToInt32(parameter);

        double availableSpace = gridWidth - minWidth;
        if (imageWidth > availableSpace)
            return new GridLength(availableSpace, GridUnitType.Pixel);

        return new GridLength(0, GridUnitType.Auto);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

, Grid , , Grid, , , , , . Source.Width, . , .

<Border>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" MinWidth="200" />
            <ColumnDefinition>
                <ColumnDefinition.Width>
                    <MultiBinding ConverterParameter="200">
                        <MultiBinding.Converter>
                            <local:AutoColumnConverter/>
                        </MultiBinding.Converter>
                        <Binding ElementName="Img" Path="Source.Width"/>
                        <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Border}}" Path="ActualWidth"/>
                    </MultiBinding>
                </ColumnDefinition.Width>
            </ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Image x:Name="Img" Grid.Column="1" Stretch="Uniform" StretchDirection="DownOnly"
                Source="..."/>
    </Grid>
</Border>
+2

All Articles