将DataGrid列宽绑定到另一个DataGrid的两列

3

问题: 如何将StatName.Width绑定到Samp1.ActualWidth + Samp2.ActualWidth?

当前与期望的

子问题:

为什么我的WidthConverter函数从未执行(断点从未被触发)?

哪种方法是正确的<Binding ...语法用于每个MultiBinding组件?

我尝试过的:

我认为我需要使用MultiBinding和某种类型的转换器对DataGridTextColumn.Width进行赋值。

我已经尝试从各种在线示例中组合解决方案。 我似乎无法将它们全部整合在一起。

编辑

使用<Binding ElementName="Samp1" Path="ActualWidth" />

  1. 没有编译错误或警告。
  2. Convert函数没有被触发
  3. 输出中没有相关消息

使用<Binding Source="{x:Reference Samp1}" Path="ActualWidth" />

  1. 编译错误(仍然允许执行):指定的强制转换无效。对于<MultiBinding>...</MultiBinding>
  2. 重设大小时无法调用Convert,但加载时会被调用三次。
  3. 在每次执行Convert:时:

System.Windows.Data Error: 5 : BindingExpression产生的值不适用于目标属性; Value='40' MultiBindingExpression:target element is 'DataGridTextColumn' (HashCode=64879470); target property is 'Width' (type 'DataGridLength')


尝试使用MultiBinding (xaml部分)

<Page.Resources>
    <local:WidthConverter x:Key="WidthConverter" />
</Page.Resources>

<StackPanel>

    <DataGrid IsReadOnly="True" HeadersVisibility="Column">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="Samp1" Binding="{Binding a}" Header="S1" />
            <DataGridTextColumn x:Name="Samp2" Binding="{Binding b}" Header="S2" />
            <DataGridTextColumn x:Name="Total" Binding="{Binding c}" Header="Tot" />
        </DataGrid.Columns>
        <local:MyGenericRecord a="5000" b="2500" c="7500" />
        <local:MyGenericRecord a="1000" b="1500" c="2500" />
    </DataGrid>

    <DataGrid IsReadOnly="True" HeadersVisibility="Column">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="StatName"  Binding="{Binding a}" Header="Stat">
                <DataGridTextColumn.Width>
                    <MultiBinding Converter="{StaticResource WidthConverter}">
                        <Binding ElementName="Samp1" Path="ActualWidth" />
                        <Binding ElementName="Samp2" Path="ActualWidth" />
                    </MultiBinding>
                </DataGridTextColumn.Width>
            </DataGridTextColumn>
            <DataGridTextColumn x:Name="StatValue" Binding="{Binding b}" Header="Val" Width="{Binding ElementName=Total, Path=ActualWidth}" />
        </DataGrid.Columns>
        <local:MyGenericRecord a="Min" b="2500" />
        <local:MyGenericRecord a="Max" b="7500" />
        <local:MyGenericRecord a="Average" b="5000" />
    </DataGrid>

</StackPanel>

多绑定尝试(代码部分)

public class WidthConverter : IMultiValueConverter
{

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double totalWidth = 0;

        foreach (DataGridLength Width in values)
            totalWidth += Width.Value;

        return totalWidth;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

你确定 ActualWidth 不是一个 double 吗?我尝试将 DataGridLength 改为 double,它可以工作。 - P.Manthe
@Bob 我尝试了 foreach ( double Width in values ) totalWidth += Width;。代码编译并运行了,但是“StatName”列仍然只有单词“Average”的宽度。 - Steven
@Bob 我发现 WidthConverter 函数从未被调用过。你知道为什么吗?另外,我的代码示例在你那里是否执行正确? - Steven
好的,我误解了你的问题,现在我可以重现它。我在这里找到了一些信息。我会尝试找到解决方法并告诉你。 - P.Manthe
@Steven:可能是因为VS太蠢了。通常这种错误都是由GUI设计师引起的,而我甚至从来不使用它。 - H.B.
显示剩余2条评论
1个回答

1
代码最终如下所示执行:

  • <Binding Source="{x:Reference Samp2}" Path="ActualWidth" />
  • return new DataGridLength(totalWidth);

Converter在加载和调整Samp1Samp2时被调用。列宽按预期保持同步。

<DataGridTextColumn x:Name="StatName"  Binding="{Binding a}" Header="Stat">
   <DataGridTextColumn.Width >
       <MultiBinding Converter="{StaticResource WidthConverter}">
           <Binding Source="{x:Reference Samp1}" Path="ActualWidth" />
           <Binding Source="{x:Reference Samp2}" Path="ActualWidth" />
       </MultiBinding>
   </DataGridTextColumn.Width>
</DataGridTextColumn>

“Convert” 函数需要返回一个 “DataGridLength”,这是 “DataGridTextColumn.Width” 的数据类型。
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{

    double totalWidth = 0;

    foreach (double Width in values)
        totalWidth += Width;

    return new DataGridLength(totalWidth);
}

注意:无论出现错误“指定的强制转换无效”,代码都能正常执行。

  1. Visual Studio 设计器用青色下划线标记整个标签<MultiBinding ... </MultiBinding>
  2. 错误列表窗口报告错误“指定的强制转换无效”。
  3. 虽然它被显示为错误,但 Visual Studio 仍将构建并执行该代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接