以编程方式在DataGridComboBoxColumn中获取ComboBox的内容

时间:2019-02-07 14:25:58

标签: c# wpf data-binding datagrid

我有一个从DataGrid派生的类,当所有列都是DataGridTextColumns时,它可以很好地工作,并允许我提取每列中的不同字符串。但是,我不得不对其进行扩展以允许使用DataGridComboBox列,但是我找不到找到这些字符串的方法。

如果我有一个DataGridTextColumn,则可以使用下面的代码来获取包含字符串的不同值的排序列表。这段代码在我的子类DataGrid中,并且不需要在运行时知道数据源或数据源类型。

        var type = this.Items[0].GetType();
        var propertyInfo = type.GetProperty(columnName);

        // Sorts the Items in the natural order for the property/column used
        // then gets just that property as strings
        // distinct etc.
        List<string> query = this.Items.Cast<object>()
            .OrderBy(i => propertyInfo.GetValue(i))
            .Select(i => $"{propertyInfo.GetValue(i)}")
            .Distinct()
            .ToList();
        return query;

DataGridComboBoxColumn链接到对象的SupplierId,我找不到将SupplierId转换为供应商名称的方法。这是列定义的XAML。

                <DataGridComboBoxColumn 
                Header="Supplier"
                SelectedValueBinding="{Binding SupplierId, Mode=TwoWay}" 
                DisplayMemberPath="Name"
                SelectedValuePath="Id">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.SuppliersList, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.SuppliersList, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>


public class MyObject
{
     public int SupplierId { get; set; }
     // other properties
}

public class Supplier
{
    public int Id { get; set; }
    public string Name  { get; set; }
}

我已经到了无法实现的地步,我将不得不重新设计DataGrid类,但我真的不愿意。

1 个答案:

答案 0 :(得分:1)

您的数据项,即this.Items中的对象,没有要检索的名称。它仅具有SupplierId属性。

因此,为了获得在ComboBox中显示的名称,您需要从SuppliersList未知的DataGrid或视觉对象中获取名称。 ComboBox元素,仅适用于已加载到可视化树中的行。

是的,您可能应该重新考虑您的设计。

如果您确实想获得视觉ComboBox元素的引用,请参见以下示例:

foreach (object item in this.Items)
{
    DataGridRow row = this.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
    if (row != null)
    {
        ComboBox cmb = FindVisualChildren<ComboBox>(row)?.FirstOrDefault();
        if (cmb != null)
        {
            string name = cmb.Text;
        }
    }
}

Find all controls in WPF Window by type