我在Grid
上使用MultiBinding
和MultiValueConverter
,以便根据所有Grid.Row
s的ActualHeight
设置每个Grid.Row
的MaxHeight
。
<RowDefinition x:Name="grdRow1" Height="Auto" >
<RowDefinition.MaxHeight>
<MultiBinding Converter="{StaticResource CalculateMaxHeightConverter}" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding Path="ActualHeight" ElementName="grdRow1" />
<Binding Path="ActualHeight" ElementName="grdRow2" />
<Binding Path="ActualHeight" ElementName="grdRow3" />
<Binding Path="ActualHeight" ElementName="grdRow4" />
<Binding Path="ActualHeight" ElementName="grdRow5" />
</MultiBinding>
</RowDefinition.MaxHeight>
</RowDefinition>
多转换器:
public class AvailableHeightConverter : IMultiValueConverter
{
public double PanelHeight { get; set; }
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null)
return Binding.DoNothing;
double currentHeight = 0d;
double availableHeight = 0d;
foreach (object value in values)
{
currentHeight += (double)value;
}
availableHeight = PanelHeight - currentHeight;
if (availableHeight < 0)
return Binding.DoNothing;
return availableHeight;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
UserControl.资源:
<cvc:AvailableHeightConverter x:Key="CalculateMaxHeightConverter" PanelHeight="1080" />
我的问题(一个伪问题)是,每当Grid.Row
的ActualHeight
发生变化时,我都无法弄清楚如何使用UpdateSourceTrigger
。
您的xaml有两个问题(据我所见,没有亲自尝试)
- ActualHeight没有设置器,因此需要使用Mode="单向"
- 将grdRow1的MaxHeight绑定到所有行ActualHeight(包括grdRow1本身)可能会产生一个无休止的调整大小循环
尝试以下操作:
<RowDefinition x:Name="grdRow1" Height="Auto" >
<RowDefinition.MaxHeight>
<MultiBinding Converter="{StaticResource CalculateMaxHeightConverter}" Mode="OneWay" UpdateSourceTrigger="PropertyChanged">
<Binding Path="ActualHeight" ElementName="grdRow2" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="grdRow3" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="grdRow4" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="grdRow5" Mode="OneWay" />
</MultiBinding>
</RowDefinition.MaxHeight>
</RowDefinition>
好。在试验了各种各样的senarios之后,我发现Binding
行的ActualHeight
不会通知MultiBinding
更改。@christoph注意到的(2.)也很有帮助。所以我最终绑定了TextBox
的ActualWidth
,如下所示:
对于第1行
<RowDefinition x:Name="grdRow1" Height="Auto" >
<RowDefinition.MaxHeight>
<MultiBinding Converter="{StaticResource CalculateMaxHeightConverter}">
<Binding Path="ActualHeight" ElementName="txtBox2" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="txtBox3" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="txtBox4" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="txtBox5" Mode="OneWay" />
</MultiBinding>
</RowDefinition.MaxHeight>
</RowDefinition>
对于第2行
<RowDefinition x:Name="grdRow2" Height="Auto" >
<RowDefinition.MaxHeight>
<MultiBinding Converter="{StaticResource CalculateMaxHeightConverter}">
<Binding Path="ActualHeight" ElementName="txtBox1" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="txtBox3" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="txtBox4" Mode="OneWay" />
<Binding Path="ActualHeight" ElementName="txtBox5" Mode="OneWay" />
</MultiBinding>
</RowDefinition.MaxHeight>
</RowDefinition>
并且从(AvailableHeightConverter
的)CCD_ 17减去一行的CCD_。
<cvc:AvailableHeightConverter x:Key="CalculateMaxHeightConverter" PanelHeight="1028" />
(过去是1080(一行的-52 MinHeight
)