Wpf 网格.行动态调整大小

Wpf 网格.行动态调整大小,wpf,grid,height,multibinding,Wpf,Grid,Height,Multibinding,我在网格上使用多重绑定和多值转换器,以便根据所有网格行的实际高度设置每个网格行的最大高度 <RowDefinition x:Name="grdRow1" Height="Auto" > <RowDefinition.MaxHeight> <MultiBinding Converter="{StaticResource CalculateMaxHeig

我在
网格上使用
多重绑定
多值转换器
,以便根据所有
网格行的
实际高度
设置每个
网格行的
最大高度

               <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();
    }
}
<cvc:AvailableHeightConverter x:Key="CalculateMaxHeightConverter" PanelHeight="1080" />
public类可用权重转换器:IMultiValueConverter
{
公共双面板高度{get;set;}
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
如果(值==null)
不做任何事;
双电流高度=0d;
双可用高度=0d;
foreach(值中的对象值)
{
currentHeight+=(双精度)值;
}
可用高度=面板高度-当前高度;
如果(可用高度<0)
不做任何事;
返回可用重量;
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
UserControl.Resources:

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();
    }
}
<cvc:AvailableHeightConverter x:Key="CalculateMaxHeightConverter" PanelHeight="1080" />


我的问题(一个虚拟问题)是,每当
网格行的
实际高度发生变化时,我都不知道如何
更新sourcetrigger

您的xaml有两个问题(据我所知,不必亲自尝试)

  • 实际高度没有设置器,因此需要使用Mode=“单向”
  • 将grdRow1的MaxHeight绑定到包括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进行实验后,我发现
    绑定
    行的
    实际高度
    不会通知
    多绑定
    进行更改。@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>
    

    (过去是一行的1080(-52
    MinHeight

    尝试将接口InotifyProperty更改为类。如果某些属性发生更改,这将自动通知UI,但在多值转换器中不需要它,但您需要一些东西来触发更新源?是吗?是的,但IMultiValueConverter应该能够检测到作为
    values[]
    ActualHeight
    更改时仍不更新。我认为这与所述的
    ActualHeight
    属性的只读问题有关。