IMultiValueConverter 的 DataGridTextColumn 绑定不起作用
DataGridTextColumn binding for IMultiValueConverter not working
我有这个 DataGridTextColumn,我正试图在其上放置一个 IMultiValueConverter。
在转换器中,当我执行以下操作时,GenericDataGrid 的绑定:
Console.WriteLine(values[1].GetType());
返回 MS.Internal.NamedObject
我该如何解决这个问题,以便它为我提供对 DataGrid 的引用?
<DataGrid Name="GenericDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding UserCollection}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Job_Title}">
<DataGridTextColumn.Header>
<MultiBinding Converter="{StaticResource metaDataDisplayNameConverter}">
<MultiBinding.Bindings>
<Binding RelativeSource="{x:Static RelativeSource.Self}"/>
<Binding ElementName="GenericDataGrid" />
</MultiBinding.Bindings>
</MultiBinding>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
[编辑]
这是我制作绑定代理后的结果,但是 Path="Data"
有问题。输入后我得到 Object reference not set to an instance of an object
.
你能看出代理绑定有什么问题吗?
<DataGrid Name="GenericDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding UserCollection}">
<DataGrid.Resources>
<proxy:FreezableBindingProxy x:Key="proxy" Data="{Binding ElementName=GenericDataGrid}" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Job_Title}">
<DataGridTextColumn.Header>
<MultiBinding Converter="{StaticResource metaDataDisplayNameConverter}">
<MultiBinding.Bindings>
<Binding RelativeSource="{x:Static RelativeSource.Self}"/>
<Binding Source="{StaticResource proxy}" Path="Data" />
</MultiBinding.Bindings>
</MultiBinding>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
[编辑 2]
另一个相关的问题。在转换器中,当我尝试获取 DataGrid 的 ItemsSource 时,它抛出了一堆错误。知道为什么会这样吗?
我唯一追求的是集合类型,也许有更好的方法。
实际上我收回这一点,重要的是集合中的单一项目类型。
public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string DisplayName = "Col";
object ColumnObject = values[0];
DataGrid dg = (DataGrid)values[1];
string columnPropertyName = parameter.ToString();
var collection = dg.ItemsSource; //*****Fails here*****
Type collectionType = collection.GetType();
Type itemType = collectionType.GetGenericArguments().Single();
PropertyInfo prop = itemType.GetProperties().SingleOrDefault(p => p.Name.Equals(columnPropertyName));
//....Gets properties display name attribute here.
return DisplayName;
}
错误:
A first chance exception of type 'System.NullReferenceException' occurred in UserManagement.dll
A first chance exception of type 'System.NullReferenceException' occurred in System.Xaml.dll
A first chance exception of type 'System.NullReferenceException' occurred in PresentationFramework.dll
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
Rachel 在这个问题上给出了 good explanation。
The DataGridColumn is not actually part of the VisualTree, so bindings on the class cannot find their source
她为此提供了一个解决方法,我尝试了以下步骤并且成功了。
1.Create新建一个classBindingProxy
并添加到项目中,代码来自this answer, I add a try-catch抑制Object reference not set to an instance of an object
抛出的异常设计时的构造函数。
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
try
{
return new BindingProxy();
}
catch
{
return null;
}
}
#endregion
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(BindingProxy));
}
2.And XAML 代码
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding ElementName=GenericDataGrid}" />
<local:MetaDataDisplayNameConverter x:Key="metaDataDisplayNameConverter" />
</Window.Resources>
<Grid>
<DataGrid Name="GenericDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding UserCollection}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Job_Title}">
<DataGridTextColumn.Header>
<MultiBinding Converter="{StaticResource metaDataDisplayNameConverter}">
<MultiBinding.Bindings>
<Binding RelativeSource="{x:Static RelativeSource.Self}" />
<Binding Source="{StaticResource proxy}" Path="Data" />
</MultiBinding.Bindings>
</MultiBinding>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
我有这个 DataGridTextColumn,我正试图在其上放置一个 IMultiValueConverter。
在转换器中,当我执行以下操作时,GenericDataGrid 的绑定:
Console.WriteLine(values[1].GetType());
返回 MS.Internal.NamedObject
我该如何解决这个问题,以便它为我提供对 DataGrid 的引用?
<DataGrid Name="GenericDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding UserCollection}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Job_Title}">
<DataGridTextColumn.Header>
<MultiBinding Converter="{StaticResource metaDataDisplayNameConverter}">
<MultiBinding.Bindings>
<Binding RelativeSource="{x:Static RelativeSource.Self}"/>
<Binding ElementName="GenericDataGrid" />
</MultiBinding.Bindings>
</MultiBinding>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
[编辑]
这是我制作绑定代理后的结果,但是 Path="Data"
有问题。输入后我得到 Object reference not set to an instance of an object
.
你能看出代理绑定有什么问题吗?
<DataGrid Name="GenericDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding UserCollection}">
<DataGrid.Resources>
<proxy:FreezableBindingProxy x:Key="proxy" Data="{Binding ElementName=GenericDataGrid}" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Job_Title}">
<DataGridTextColumn.Header>
<MultiBinding Converter="{StaticResource metaDataDisplayNameConverter}">
<MultiBinding.Bindings>
<Binding RelativeSource="{x:Static RelativeSource.Self}"/>
<Binding Source="{StaticResource proxy}" Path="Data" />
</MultiBinding.Bindings>
</MultiBinding>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
[编辑 2]
另一个相关的问题。在转换器中,当我尝试获取 DataGrid 的 ItemsSource 时,它抛出了一堆错误。知道为什么会这样吗?
我唯一追求的是集合类型,也许有更好的方法。
实际上我收回这一点,重要的是集合中的单一项目类型。
public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string DisplayName = "Col";
object ColumnObject = values[0];
DataGrid dg = (DataGrid)values[1];
string columnPropertyName = parameter.ToString();
var collection = dg.ItemsSource; //*****Fails here*****
Type collectionType = collection.GetType();
Type itemType = collectionType.GetGenericArguments().Single();
PropertyInfo prop = itemType.GetProperties().SingleOrDefault(p => p.Name.Equals(columnPropertyName));
//....Gets properties display name attribute here.
return DisplayName;
}
错误:
A first chance exception of type 'System.NullReferenceException' occurred in UserManagement.dll
A first chance exception of type 'System.NullReferenceException' occurred in System.Xaml.dll
A first chance exception of type 'System.NullReferenceException' occurred in PresentationFramework.dll
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
Rachel 在这个问题上给出了 good explanation。
The DataGridColumn is not actually part of the VisualTree, so bindings on the class cannot find their source
她为此提供了一个解决方法,我尝试了以下步骤并且成功了。
1.Create新建一个classBindingProxy
并添加到项目中,代码来自this answer, I add a try-catch抑制Object reference not set to an instance of an object
抛出的异常设计时的构造函数。
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
try
{
return new BindingProxy();
}
catch
{
return null;
}
}
#endregion
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(BindingProxy));
}
2.And XAML 代码
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding ElementName=GenericDataGrid}" />
<local:MetaDataDisplayNameConverter x:Key="metaDataDisplayNameConverter" />
</Window.Resources>
<Grid>
<DataGrid Name="GenericDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding UserCollection}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Job_Title}">
<DataGridTextColumn.Header>
<MultiBinding Converter="{StaticResource metaDataDisplayNameConverter}">
<MultiBinding.Bindings>
<Binding RelativeSource="{x:Static RelativeSource.Self}" />
<Binding Source="{StaticResource proxy}" Path="Data" />
</MultiBinding.Bindings>
</MultiBinding>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>