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

时间:2017-12-11 21:59:25

标签: c# wpf xaml data-binding multibinding

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

Current vs desired

子的问题:

为什么我的WidthConverter函数从未执行过(断点从未命中)?

各个MultiBinding组件的正确<Binding ...语法是什么?

我尝试了什么:

我想我需要为DataGridTextColumn.Width分配MultiBinding和某种类型的转换器。

我尝试在线提供各种示例的解决方案。我似乎无法全力以赴。

修改

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

  1. 没有构建错误或警告。
  2. 未点击Convert功能
  3. 输出中没有相关消息
  4. 使用<Binding Source="{x:Reference Samp1}" Path="ActualWidth" />

    1. 构建错误(仍允许执行):指定的强制转换无效。对于<MultiBinding>...</MultiBinding>
    2. 加载时,
    3. Convert被调用三次。调整大小时不会调用它 专栏Samp1
    4. 每次执行Convert:
    5. System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='40' MultiBindingExpression:target element is 'DataGridTextColumn' (HashCode=64879470); target property is 'Width' (type 'DataGridLength')

      MultiBinding Attempt(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>
      

      MultiBinding Attempt(代码部分)

      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;
          }
      }
      

1 个答案:

答案 0 :(得分:1)

代码最终按预期执行,具有以下内容:

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

在调整ConverterSamp1时调用Samp2。列宽按预期保持同步。

<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);
}

注意:代码按预期执行,无论错误Specified cast is not valid.

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