I am using MultiBinding
and a MultiValueConverter
on a Grid
in order to set the MaxHeight
of each Grid.Row
according to the ActualHeight
of all Grid.Row
s.
<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>
MultiConverter:
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.Resources:
<cvc:AvailableHeightConverter x:Key="CalculateMaxHeightConverter" PanelHeight="1080" />
My problem (a dummy one) is that i cannot figure out how to UpdateSourceTrigger
whenever the ActualHeight
of a Grid.Row
is being changed.
OK. After experimenting with various senarios i ended up that Binding
row's ActualHeight
doesn't notify MultiBinding
for changes. Also what @christoph noticed (2.) was very helpful. So i ended up binding TextBox
's ActualWidth
as shown below:
for Row 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>
for Row 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>
and subtract the Height
of one row from the PanelHeight
(of AvailableHeightConverter
).
<cvc:AvailableHeightConverter x:Key="CalculateMaxHeightConverter" PanelHeight="1028" />
(Used to be 1080 (-52 MinHeight
of a Row)