无法使用多重绑定绑定 DataGrid ItemsSource - 简单绑定工作正常

Cannot bind DataGrid ItemsSource with multibinding - simple binding works fine

我遇到了一个奇怪的问题。我有一个 DataGrid,我想用 MultiBinding 绑定到 ItemsSource 是有原因的。虽然使用简单绑定到 DataTable 效果很好,但我无法让它与多重绑定一起使用。

简单地说:下面的标记有效并呈现数据 table

<DataGrid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" AutoGenerateColumns="True" IsReadOnly="True">
    <DataGrid.ItemsSource>
        <Binding Path="Mock.Value" Converter="{StaticResource CollectionToDataTableConverter}"></Binding>
    </DataGrid.ItemsSource>
</DataGrid>

...虽然这实际上不起作用 - 什么也不渲染

<DataGrid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" AutoGenerateColumns="True" IsReadOnly="True">
    <DataGrid.ItemsSource>
        <MultiBinding Converter="{StaticResource CollectionToDataTableConverter}">
            <Binding Path="Mock.Value" />
        </MultiBinding>
    </DataGrid.ItemsSource>
</DataGrid>

请注意 CollectionToDataTableConverter 实现了 IValueConverterIMultiValueConverter 并且只是传递值

public class CollectionToDataTableConverter : IMultiValueConverter, IValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values?.FirstOrDefault();
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
    // ...
}

当然 Mock.Value 属性 存在于视图模型中并且是一个简单的 DataTable。此外,调试证明在这两种情况下转换器 returns 都是正确的值。

你知道这是怎么回事吗?

谢谢!

首先,DataTable 没有实现 IEnumerable,因此它不是 DataGrid.ItemsSource 属性 的有效值。您可以在输出 window 中观察到 System.Windows.Data Error: 5 就是这样说的。

其次,当绑定到 DataTable 时,您可以轻松地检查 DataGrid.ItemsSource 的最终值实际上是一个 DataView 对象(准确地说是 DataTable.DefaultView 的值属性).

现在有几种方法可以使 MultiBinding 工作 - 这里有几个:

  • Return DataTable.DefaultView 而不是转换器中的 DataTable 本身
  • 直接绑定到 DataTable.DefaultView(使用 Mock.Value.DefaultView 作为绑定路径)
  • 创建一个从 DataTable 派生并实现 IEnumerable 的 class(GetEnumerator 实现中的 return DefaultView.GetEnumerator()),并使用它class 而不是 DataTable

至于解释它在不使用 MultiBinding 时如何 自动 工作,或者为什么在使用 MultiBinding 时不是这样 - 我不知道。我认为这是 WPF 的类型转换机制,但 DataTableIEnumerable 的默认转换器都无法执行转换,所以我想不是这样。可能 Binding class 在这方面有一些 MultiBinding 没有的特殊能力。