如何通过度量影响所需大小
本文关键字:影响 何通过 度量 | 更新日期: 2023-09-27 17:56:07
我正在使自定义面板更能响应设计我的应用程序。
但是有些事情困扰着我。在我覆盖 MeasureOveroverride 的过程中,我在面板的所有子项上调用 Measure。
我的孩子是像下面这样的网格:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition MinWidth="150" MaxWidth="220"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition MinWidth="150" MaxWidth="220"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Formulaire 1" Grid.ColumnSpan="4" Grid.Column="1" Style="{DynamicResource Heading1}"/>
<Label Content="Label1" HorizontalAlignment="Left" Grid.Row="1" Grid.Column="1"/>
<Label Content="Label2" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="1"/>
<Label Content="Label3" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="1"/>
<Label Content="Label4" HorizontalAlignment="Left" Grid.Row="4" Grid.Column="1"/>
<Label Content="Label5" HorizontalAlignment="Left" Grid.Row="5" Grid.Column="1"/>
<Label Content="Label6" HorizontalAlignment="Left" Grid.Row="1" Grid.Column="3"/>
<Label Content="Label7" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="3"/>
<Label Content="Label8" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="3"/>
<Label Content="Label9" HorizontalAlignment="Left" Grid.Row="4" Grid.Column="3"/>
<Label Content="Label10" HorizontalAlignment="Left" Grid.Row="5" Grid.Column="3"/>
<Label Content="Message" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="6" Grid.Column="1" />
<TextBox Grid.Column="2" Grid.Row="1"/>
<TextBox Grid.Column="2" Grid.Row="2"/>
<TextBox Grid.Column="2" Grid.Row="3"/>
<TextBox Grid.Column="2" Grid.Row="4"/>
<TextBox Grid.Column="2" Grid.Row="5"/>
<TextBox Grid.Column="4" Grid.Row="1"/>
<TextBox Grid.Column="4" Grid.Row="2"/>
<TextBox Grid.Column="4" Grid.Row="3"/>
<TextBox Grid.Column="4" Grid.Row="4"/>
<TextBox Grid.Column="4" Grid.Row="5"/>
<TextBox Grid.ColumnSpan="3" Grid.Column="2" Grid.Row="6" Height="85" />
</Grid>
此网格的最小期望宽度为 ~407,最大期望宽度为 ~547。 +- 140 基于列的最小和最大宽度。
但是,在调用 Measure 时,其可用宽度(远)优于最大所需宽度。他所需尺寸的宽度保持在最小值。
什么不会根据可用空间改变所需的大小?
除了具有
最小和最大宽度的两列之外,您已将所有行和列指定为"auto"。"GridLength.Auto"根据以下标准计算宽度(或高度):足以适应内容的最小宽度(或高度)。
因此,在网格上调用 Measure() 将返回一个 DesiredSize,该大小恰好足以适合整个网格的内容。不多也不少。您必须使用"星形大小"至少包含一个行和列定义,才能将其扩展到您提供的可用宽度。
我决定从网格继承并覆盖 MeasureOverride 以采用星形和最小/最大值来计算所需的大小。我的面板工作得更好,它应该没有副作用(至少我还没有注意到)。
在我看来,它在包装面板中的响应也更好,孩子会尝试 fo fit,然后在包装面板之后会尝试在同一行中插入下一个孩子,否则会换行。
我真的不明白为什么这不是默认行为。
对谁感兴趣 :
public class CustomGrid : Grid
{
protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
{
//I assume Grid.MeasureOverride return the minimum size as desired size
Size MinimumDesiredSize = base.MeasureOverride(constraint);
//The remaining available space provided by the container
double ConstraintWidthRemaining = constraint.Width - MinimumDesiredSize.Width;
//The supposed remaining space if we assume than star columns width equals 0, will be calculated later
double WidthRemaining = ConstraintWidthRemaining;
//The width used in the remaining available space
double WidthUsed = 0;
//The number of column which are star sized
double StarSum = 0;
foreach (ColumnDefinition column in ColumnDefinitions.Where(c => c.Width.IsStar))
{
StarSum += column.Width.Value;
WidthRemaining += column.MinWidth;
}
foreach (ColumnDefinition column in ColumnDefinitions.Where(c => c.Width.IsStar))
{
double Ratio = column.Width.Value / StarSum;
double ColumnWidth = WidthRemaining * Ratio;
if (column.MaxWidth != 0.0)
{
if (ColumnWidth > column.MinWidth)
{
if (ColumnWidth <= column.MaxWidth)
{
WidthUsed += ColumnWidth - column.MinWidth;
}
else
{
WidthUsed += column.MaxWidth - column.MinWidth;
}
}
}
else
{
WidthUsed += ColumnWidth - column.MinWidth;
}
}
MinimumDesiredSize.Width += WidthUsed;
return MinimumDesiredSize;
}
}