【问题标题】:How do I implement a multicolumn ComboBox DataGridColumn in a WPF DataGrid?如何在 WPF DataGrid 中实现多列 ComboBox DataGridColumn?
【发布时间】:2011-11-02 08:32:43
【问题描述】:

我有一个简单的问题,我认为没有简单的解决方案。我的 WPF DataGrid 中的某些网格列需要一个多列组合框。是否有已知的最佳实践来实现这一目标?根据我收集到的信息,这将需要对 DataGridComboBoxColumn 进行子类化以支持自定义 ComboBox。

我找到了一些示例,但不支持 EF 实体(我使用的是 Code First EF)。

非常感谢任何建议。谢谢

注意:这一切都是用 C# 动态完成的。我没有使用 XAML 来定义列。

更新:我所说的多列的意思是,当您将 ComboBox 放下时,我需要为“Display”显示两个值,即使在幕后我当然仍然只是存储一个身份证。

请看这里:。 http://www.telerik.com/ClientsFiles/188010_multicolumn-dropdown.JPG

除了我需要将其作为可以动态创建并添加到网格中的 DataGridColumn 来执行之外,而不仅仅是图像中显示的简单组合。

更新 我终于在 CodeProject 上找到了一篇文章,作者根据我的 -exact- 要求开发了一个控件。它位于here。现在我要解决的唯一问题是如何在使用实体框架时允许控件工作(特别是代码优先)。越来越近了!

【问题讨论】:

  • 对于阅读此内容的其他人,我必须修改 CustComboBox.cs 文件中的 popupDataGrid_MouseDown 事件以仅设置 SelectedItem,而不是 SelectedValue,因为这会在我绑定到 SelectedItem 时导致堆栈溢出在 XAML 中。

标签: wpf datagrid dynamic datagridcomboboxcolumn multiple-columns


【解决方案1】:

我已经找到了适合我特定场景的解决方案。我从上面上次更新中的链接下载了包含 DataGridComboBoxColumn 子类的自定义多列 ComboBox。基本上我只是使用 Entity Framework Code-First POCO 完成了这项工作,它解决了我的问题。这是我必须做的才能使其与 POCO 一起使用。

在 CustDataGridComboBoxColumn 内部有一些覆盖。您只需要稍微修改以下两个覆盖。我正在使用反射来更改设置属性,因为我不知道控件将是什么。

最初的实现是通过使用 SelectedValuePath 从 DataRowView 中获取正确的 Row 来实现的。

protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
{
      DataGridCell cell = editingEventArgs.Source as DataGridCell;
      if (cell != null)
      {
        // Changed to support EF POCOs
        PropertyInfo info = editingElement.DataContext.GetType().GetProperty("YourPropertyName", BindingFlags.Public | BindingFlags.Instance);
        object obj = info.GetValue(editingElement.DataContext, null);
        comboBox.SelectedValue = obj;
      }
      return comboBox.SelectedItem;
}

protected override bool CommitCellEdit(FrameworkElement editingElement)
{
    // Dynamically set the item on our POCO (the DataContext).
    PropertyInfo info = editingElement.DataContext.GetType().GetProperty(“YourPropertyName”, BindingFlags.Public | BindingFlags.Instance);
    info.SetValue(editingElement.DataContext, comboBox.SelectedValue, null);
    return true;
}

此外,如果您打算完全在代码中而不是在 XAML 中动态创建此自定义控件,则必须将设置器添加到 Columns 属性,因为默认情况下它设置为只读。

//The property is default and Content property for CustComboBox
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ObservableCollection<DataGridTextColumn> Columns
{
    get
    {
       if (this.columns == null)
       {
           this.columns = new ObservableCollection<DataGridTextColumn>();
       }
       return this.columns;
    }
    set
    {
       this.columns = value;
    }
}

感谢您提供的意见和答案。抱歉,我最初无法充分表达这个问题以使其更有意义。

【讨论】:

    【解决方案2】:

    你能解释一下你所说的多重是什么意思吗?

    您是否正在寻找类似以下任何一种的东西?

    [Column] (Combo) (Combo) (Combo) [Column]
    
    or
    
    [Column] 
    (Combo) 
    (Combo) 
    (Combo) 
    [Column]
    

    如果是这样,您将需要使用 DataGridTemplateColumn 类型为列实现单元格模板。

    http://windowsclient.net/wpf/wpf35/wpf-35sp1-toolkit-datagrid-feature-walkthrough.aspx

    您可以在 XAML 中进行设置,然后只需向网格提供一个集合以进行绑定,该集合将根据需要呈现列。

    【讨论】:

      【解决方案3】:

      “YourPropertyName”的含义是: PropertyInfo info = editingElement.DataContext.GetType().GetProperty("YourPropertyName", BindingFlags.Public | BindingFlags.Instance);

      【讨论】:

        猜你喜欢
        • 2014-08-29
        • 1970-01-01
        • 2016-04-30
        • 2010-10-14
        • 2011-08-23
        • 2014-01-03
        • 2013-06-30
        • 1970-01-01
        • 2011-09-01
        相关资源
        最近更新 更多