无法使用多重绑定绑定 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
实现了 IValueConverter
和 IMultiValueConverter
并且只是传递值
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 的类型转换机制,但 DataTable
和 IEnumerable
的默认转换器都无法执行转换,所以我想不是这样。可能 Binding
class 在这方面有一些 MultiBinding
没有的特殊能力。
我遇到了一个奇怪的问题。我有一个 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
实现了 IValueConverter
和 IMultiValueConverter
并且只是传递值
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
实现中的 returnDefaultView.GetEnumerator()
),并使用它class 而不是DataTable
至于解释它在不使用 MultiBinding
时如何 自动 工作,或者为什么在使用 MultiBinding
时不是这样 - 我不知道。我认为这是 WPF 的类型转换机制,但 DataTable
和 IEnumerable
的默认转换器都无法执行转换,所以我想不是这样。可能 Binding
class 在这方面有一些 MultiBinding
没有的特殊能力。