I'm facing a weird issue. I have a DataGrid
that I want to bind to ItemsSource
with MultiBinding
for a reason. While using simple binding to a DataTable
works well, I cannot get this to work with multibinding.
Simply put: the markup below works and renders the data 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>
... while this does not really work - renders nothing
<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>
Notice that CollectionToDataTableConverter
implements both IValueConverter
and IMultiValueConverter
and simply passes the value
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;
}
// ...
}
Certainly the Mock.Value
property exists on the view model and is a simple DataTable
. Also, debugging proves that in both cases the converter returns a proper value.
Do you have any idea what is going on with this?
Thanks!
First of all, DataTable
does not implement IEnumerable
, so it's not a valid value for DataGrid.ItemsSource
property. You can observe a System.Windows.Data Error: 5
in the output window saying just that.
Second, you can easily check that the final value of DataGrid.ItemsSource
when binding to a DataTable
is actually a DataView
object (precisely it's the value of DataTable.DefaultView
property).
Now there are several ways to make a MultiBinding
work - here's a couple:
DataTable.DefaultView
rather than the DataTable
itself in your converterDataTable.DefaultView
(use Mock.Value.DefaultView
as binding path)DataTable
and implementing IEnumerable
(return DefaultView.GetEnumerator()
in the GetEnumerator
implementation), and use that class instead of DataTable
As for an explanation for how does it automagically work when not using MultiBinding
or why it's not the case when using one - I don't know. I thought it was WPF's type conversion mechanism, but default converters neither for DataTable
nor for IEnumerable
are capable of performing the conversion, so I guess that's not it. Possibly the Binding
class has some special capabilities regarding that matter that MultiBinding
does not.