【问题标题】:Get the contents of the ComboBox in a DataGridComboBoxColumn programmatically以编程方式获取 DataGridComboBoxColumn 中 ComboBox 的内容
【发布时间】:2019-02-07 14:25:57
【问题描述】:

我有一个派生自 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 类,但我真的不想这样做。

【问题讨论】:

  • 您应该研究 mvvm,从控件中获取数据是使用 wpf 的一种非常糟糕的方式。从视图模型绑定数据。处理那里的数据。
  • @Andy 我正在使用 mvvm。使用 DatGridTextColumn 我可以使用绑定来获取我需要的数据。不幸的是,组合框列不那么适应。我将更改我的设计以使用弹出窗口来代替

标签: c# wpf data-binding datagrid


【解决方案1】:

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

因此,为了获取显示在ComboBox 中的名称,您需要从SuppliersListDataGrid 未知)或视觉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

【讨论】:

  • 感谢您的回答,我对 ContainerFromItem 不熟悉。可悲的是,这只会获得屏幕上可见的项目,通过向下滚动我会返回不同的字符串集。看来我要打破重构枪了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 2013-02-25
  • 2021-12-15
  • 2018-08-29
  • 2015-05-17
相关资源
最近更新 更多