简体   繁体   中英

DataGridTextColumn binding for IMultiValueConverter not working

I have this DataGridTextColumn that I'm trying to place a IMultiValueConverter on.

In the converter the binding for GenericDataGrid when I do a: Console.WriteLine(values[1].GetType()); comes back as MS.Internal.NamedObject

How can I fix this so it gives me a reference to the 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>

[EDIT]

This is what I have after making a Binding Proxy, but this has problem with Path="Data" . After I enter this I get Object reference not set to an instance of an object .

Can you see what the issue is with the proxy binding?

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

在此处输入图片说明

[EDIT 2]

One other issue that is related. In the converter when I try to get the DataGrid's ItemsSource it is throwing a heap of errors. Any idea why that would be happening?

The only thing I'm after is the collection type, maybe there's a better way.
Actually I take that back it's the singular item type that is in the collection that's the important one.

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

Errors:

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 gives a good explanation on this issue.

The DataGridColumn is not actually part of the VisualTree, so bindings on the class cannot find their source

And she provides a workaround for it, I try the following steps and it works.

1.Create a new class BindingProxy and add it to the project, the code is from this answer , I add a try-catch to suppress the Object reference not set to an instance of an object exception thrown by the constructor at design time.

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 the XAML code

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM