C#: DataGridViewComboBoxColumn Displaying Different Values in Drop Down List


You can add a DataGridViewComboBoxColumn to the DataGridView to allow your users the ability to select from a list of items when editing the cell’s contents. I ran into a situation today where I needed to display a description of each item in the drop down list of the ComboBox but after the user selected an item, I only wanted the name of the item to be displayed and not the description as well. The following image shows an example of what I wanted; the drop down list shows a description of each animal but when selected, only the type of the animal is shown.

Unfortunately, the DataGridViewComboBoxColumn has a single DisplayMember property that lets you specify which property of the objects bound to the control is displayed to the user. So, to allow for the desired result, I needed to change the DisplayMember property when the drop down list is visible to show both the type and description and when the drop down list is not visible, to only show the type. The code below allows us to accomplish just this.

The form is setup with a DataGridView and two columns, if which the first is a ComboBoxColumn. I have a simple Animal class as defined below.

public class Animal
{
    public string Type { get; set; }
    public string Description { get; set; }

    public string TypeAndDescription { get { return Type + " - " + Description; } }
}

At the initialization if the form, we simply add a few Animal objects to the column’s Items collection and set the default DisplayMember to Type.

public Form1()
{
    InitializeComponent();

    this.clmAnimal.Items.Add(new Animal() { Type = "Dog", Description = "Fury animal that barks" });
    this.clmAnimal.Items.Add(new Animal() { Type = "Cat", Description = "Fury animal that meows" });
    this.clmAnimal.Items.Add(new Animal() { Type = "Mouse", Description = "Small rodent with a tail" });
    this.clmAnimal.Items.Add(new Animal() { Type = "Rabbit", Description = "Small with two large ears" });            

    this.clmAnimal.DisplayMember = "Type";
    this.clmAnimal.DropDownWidth = 180;
}

From the designer, there is no way to wire up the DataGridViewComboBoxColumn DropDown and DropDownClosed events. To do this, we need to handle the EditingControlShowing event of the DataGridView. This event fires when a control used for editing the value in the DataGridView is shown. This event will be fired when the user clicks on the cell to select an item from the ComboBox. Add the following code to this event.

private void dataGridViewAnimals_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    // Cast the editing control to a ComboBox
    ComboBox cmbBx = e.Control as ComboBox;

    // If the cast was successful, wire up the DropDown and DropDownClosed events
    if (cmbBx != null)
    {
        cmbBx.DropDown -= new EventHandler(ComboBoxCell_DropDown);
        cmbBx.DropDown += new EventHandler(ComboBoxCell_DropDown);

        cmbBx.DropDownClosed -= new EventHandler(ComboBoxCell_DropDownClosed);
        cmbBx.DropDownClosed += new EventHandler(ComboBoxCell_DropDownClosed);
    }
}

Then add the following code to handle the DropDown and DropDownClosed events.

private void ComboBoxCell_DropDown(object sender, EventArgs e)
{
    // When the drop down list appears, change the DisplayMember property of the ComboBox
    // to 'TypeAndDescription' to show the description
    DataGridViewComboBoxEditingControl cmbBx = sender as DataGridViewComboBoxEditingControl;
    if (cmbBx != null)
        cmbBx.DisplayMember = "TypeAndDescription";
}

private void ComboBoxCell_DropDownClosed(object sender, EventArgs e)
{
    // When the drop down list is closed, change the DisplayMember property of the ComboBox
    // back to 'Type' to hide the description
    DataGridViewComboBoxEditingControl cmbBx = sender as DataGridViewComboBoxEditingControl;
    if (cmbBx != null)
        cmbBx.DisplayMember = "Type";
}

The above code will allows us to display a different value when the ComboBox’s drop down list is displayed than what is displayed after the user selects an item from the list.