限制 WPF 数据网格中“自动”列的最大宽度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14462150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Limit maximum width of "Auto" column in WPF data grid
提问by aKzenT
I have a standard WPF grid with 2 columns defined as:
我有一个标准的 WPF 网格,其中 2 列定义为:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="200" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
...
</Grid>
What I want to achieve is that the second column is automatically sized based on its content and the first column gets all 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 cut off instead of being resized.
我想要实现的是第二列根据其内容自动调整大小,第一列获得所有剩余空间。但是我也希望第一列永远不会少于 200 像素。问题是,使用此配置,我的自动列将被切断而不是调整大小。
What I really want is WPF to first assign 200 pixels to the first columns, then take all remaining space and ask the content of the second column to size itself with a maximum size restriction of the remaining width. If the content needs less space, it should assign the remaining space to the first column (making it bigger than the 200 pixel).
我真正想要的是 WPF 首先将 200 像素分配给第一列,然后占用所有剩余空间并要求第二列的内容调整自身大小,并限制剩余宽度的最大大小。如果内容需要较少的空间,则应将剩余空间分配给第一列(使其大于 200 像素)。
Use case:My second column is an image with a fixed aspect ratio, so that for a given height there is an optimal width. I also have a first column with some controls that should always be visible. If there is more space available than needed I would like to assign the space to the first column instead of the second.
用例:我的第二列是具有固定纵横比的图像,因此对于给定的高度有一个最佳宽度。我还有一个第一列,其中包含一些应该始终可见的控件。如果可用空间多于需要,我想将空间分配给第一列而不是第二列。
Is there a way to achieve this with default WPF controls or do I need to write my own Grid for this?
有没有办法使用默认的 WPF 控件来实现这一点,还是我需要为此编写自己的网格?
采纳答案by Johan Larsson
The only time I saw column two being cut off was when width of column 2 + 200 was greater than the width of the grid. I played around and maybe this is a solution for you:
我唯一一次看到第 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>
I tried writing <ColumnDefinition Width="Auto" MaxWidth="400"/>but maxwidth had no effect then.
我尝试写作,<ColumnDefinition Width="Auto" MaxWidth="400"/>但当时 maxwidth 没有效果。
MaxWidth for the Viewbox is calculated as total width - the reserved 200 if that is not obvious.
Viewbox 的 MaxWidth 计算为总宽度 - 如果不明显,则保留 200。
回答by John Bowen
It sounds like what you want is basically to have 2 different modes for your second column. When there's enough space for the entire image to display at it's current height it should be Auto, otherwise it should just get the remaining space left after taking 200 for the first column. To do this kind of mode-switching you can use a converter and bind the Width for your column.
听起来您想要的基本上是为您的第二列提供两种不同的模式。当整个图像有足够的空间以当前高度显示时,它应该是自动的,否则它应该在第一列取 200 后只剩下剩余的空间。要进行这种模式切换,您可以使用转换器并绑定列的宽度。
Here you have 2 basic inputs: the total size available to the Grid, and the desired width of the image. Since you need them both you'll need an IMultiValueConverter. Here's a basic implementation to calculate the switch described above:
这里有 2 个基本输入:Grid 可用的总大小和所需的图像宽度。由于您需要它们,因此您需要一个 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();
}
}
To use this you need to wrap your Grid in another element that you can bind to instead of the Grid itself, which will essentially lie about the space available to it and try to stretch out further with the two defined columns. Here I'm using Source.Width to find the image's desired width. You may want to adjust if you care more about the aspect ratio or otherwise want to account for height too.
要使用它,您需要将您的 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>
回答by raghu sathvara
Try This Set MaxWidth
试试这个设置 MaxWidth
<Grid Height="200"
Width="600">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"
MaxWidth="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>

