3

I have a simple question that I assume does not have a simple solution. I need to have a multi-column ComboBox for some grid columns in my WPF DataGrid. Is there a known best-practice to accomplish this? From what I have gathered this will require subclassing the DataGridComboBoxColumn to support a custom ComboBox.

I have found some examples of this but not supporting EF entities (I'm using Code First EF).

Any advice is greatly appreciated. Thanks

NOTE: This is all done dynamically with C#. I'm not using XAML to define columns.

Update: What I mean by multicolumn is simply that when you drop the ComboBox down I need to show two values for "Display", even though behind the scenes of course I'm still just storing an ID.

See here:. multicolumn-dropdown http://www.telerik.com/ClientsFiles/188010_multicolumn-dropdown.JPG

With the exception that I need to do this as a DataGridColumn that can be dynamically created and added to a grid, rather than just the simple combo shown in the image.

Update I finally managed to find an article on CodeProject where the author has developed a control with my -exact- requirements. It is located here. Now the only problem I am trying to solve is how to allow the control to work when using Entity Framework (specifically, code first). Getting closer!

Sam
  • 1,509
  • 3
  • 19
  • 28
  • For anyone else reading this, I had to modify the popupDataGrid_MouseDown event in the CustComboBox.cs file to only set the SelectedItem, and not the SelectedValue, as this was causing a stackoverflow when I bind to the SelectedItem in XAML. – Brent May 03 '12 at 19:27

3 Answers3

3

I have found the solution for my particular scenario. I downloaded the custom multi-column ComboBox with the included DataGridComboBoxColumn subclass from the link in my last update above. Basically I just made this work with Entity Framework Code-First POCOs and it solved my problem. Here is what I had to do to make it work with POCOs.

Inside of the CustDataGridComboBoxColumn there are a few overrides. You just need to slightly modify the following two overrides. I’m using reflection to change set the property since I don’t know what it will be from the control.

The original implementation accomplished this by getting the correct Row from the DataRowView with SelectedValuePath.

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

Also, if you intend on creating this custom control completely in code dynamically instead of in XAML, you will have to add a setter to the Columns property because by default it is set to read-only.

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

Thanks for the views and answers provided. Sorry I was unable to adequately word the question to make more sense initially.

0

what will be "YourPropertyName" means in : PropertyInfo info = editingElement.DataContext.GetType().GetProperty("YourPropertyName", BindingFlags.Public | BindingFlags.Instance);

Mussammil
  • 864
  • 4
  • 16
  • 38
0

Can you clarify what you mean by multiple?

Are you looking to have something like either of these below?

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

or

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

If so you will need to implement a cell template for the column using the DataGridTemplateColumn Type.

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

You can set this up in XAML and then just provide a collection to the grid for binding that will render the columns as needed.

tsells
  • 2,751
  • 1
  • 18
  • 20