sommergyll.software(c#);
"Guide to Programming DataGridViewComboBoxCell in DataGridView"
 

Introduction

Implementing a DataGridViewComboBoxCell which hosts a DataGridViewComboBoxEditingControl can be quite challenging and it may take a great deal of effort and error testing before the application starts behaving as expected.

Here we will show a way to implement a DataGridViewComboBoxCell in a DataGridView control. The ComboBox control is populated with strings, which are editable. (A more advanced data source will be discussed in a later guide).

A Simple DataGridView Example

We will implement a DataGridView with three rows and two columns, see figure 1 below. The left column will work as a description for the right column. On the right column, the rows contain a TextBox cell, a ComboBox cell and another TextBox cell.

Embedded ComboBox control
Figure 1. Embedded ComboBox

In the listing below is a project in Visual Studio 2005 with an added empty DataGridView control. We now add code to create the columns, rows and embedded controls. The code is added to the Form1 constructor, just after InitializeComponent().

Once we have added a ComboBox cell to the DataGridView, we want to influence the way the embedded ComboBox control works. The only way to do this is by handling the EditingControlShowing event. In order to make the control editable, the DropDownStyle needs to be set to DropDown.

When the user edits the displayed text in the ComboBox, we (in this case) want the edited text to be added to the item collection and also be set as the new displayed text. We therefore handle one of the events being raised when we are finished editing the text by clicking somewhere else, the CellValidating event. By capturing this event, we can add any desired validation code. If the validation fails, then it is simple to cancel the event and maybe display a message.

 

If the user added text should be displayed directly when we are finished editing it (which is usually the case), it is necessary to manually commit the changes. This code should also be put in the CellValidating handler, see the inline code comments.

namespace ComboBoxTest {

public partial class Form1 : Form {

    public Form1() {
        InitializeComponent();

        dataGridView1.BorderStyle = BorderStyle.Fixed3D;

        // Add an event handler to validate the
        // cell contents when focus is leaving
        dataGridView1.CellValidating +=
            new DataGridViewCellValidatingEventHandler
                (dataGridView1_CellValidating);

        // Add this event handler to be able to 
        // configure the embedded ComboBox control
        dataGridView1.EditingControlShowing +=
            new DataGridViewEditingControlShowingEventHandler
                (dataGridView1_EditingControlShowing);

        // Change to edit mode when user enters a cell.
        dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;

        // ------------------------------------------------            
        // First create the columns
        dataGridView1.Columns.Add("NameOne", "Column One");
        dataGridView1.Columns.Add("NameTwo", "Column Two");

        // ------------------------------------------------
        // Create a row and add a textbox cell
        DataGridViewRow dataGridRow = new DataGridViewRow();
        DataGridViewCell[] cells = new DataGridViewCell[2];
        DataGridViewTextBoxCell txt1A = new DataGridViewTextBoxCell();
        DataGridViewTextBoxCell txt1B = new DataGridViewTextBoxCell();
        txt1A.Value = "textbox one";
        txt1B.Value = "content one";
        dataGridRow.Cells.Add(txt1A);
        txt1A.ReadOnly = true;
        dataGridRow.Cells.Add(txt1B);
        dataGridRow.Height = 20;
        dataGridView1.Rows.Add(dataGridRow);

        // ------------------------------------------------
        // Add a combobox cell and add the combobox items            
        dataGridRow = new DataGridViewRow();
        cells = new DataGridViewCell[2];
        DataGridViewTextBoxCell txt2A = new DataGridViewTextBoxCell();
        DataGridViewComboBoxCell cbo1 = new DataGridViewComboBoxCell();

        cbo1.Items.Add("Item one");
        cbo1.Items.Add("Item two");
        cbo1.Items.Add("Item three");

        // Set the displayed value.
        // This value needs to be present
        // in the items collection
        cbo1.Value = cbo1.Items[0];

        cbo1.ReadOnly = false;
        txt2A.Value = "a combobox";
        dataGridRow.Cells.Add(txt2A);
        txt2A.ReadOnly = true;
        dataGridRow.Cells.Add(cbo1);
        dataGridRow.Height = 20;
        dataGridView1.Rows.Add(dataGridRow);

        // ------------------------------------------------
        // Add another textbox cell
        dataGridRow = new DataGridViewRow();
        cells = new DataGridViewCell[2];
        DataGridViewTextBoxCell txt3A = new DataGridViewTextBoxCell();
        DataGridViewTextBoxCell txt3B = new DataGridViewTextBoxCell();
        txt3A.Value = "textbox two";
        txt3B.Value = "content two";
        dataGridRow.Cells.Add(txt3A);
        dataGridRow.Cells.Add(txt3B);
        dataGridRow.Height = 20;
        dataGridView1.Rows.Add(dataGridRow);
    }


    /// <summary>
    /// Event handler to allow the embedded control to wire
    /// its own event handlers and/or to set desired style
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void dataGridView1_EditingControlShowing
        (object sender,
        DataGridViewEditingControlShowingEventArgs e) {

        DataGridViewComboBoxEditingControl comboControl
            = e.Control as DataGridViewComboBoxEditingControl;
        if (comboControl != null) {
            // Set the DropDown style to get an editable ComboBox
            if (comboControl.DropDownStyle != ComboBoxStyle.DropDown) {
                comboControl.DropDownStyle = ComboBoxStyle.DropDown;
            }
        }
    }


    /// <summary>
    /// This event handler is called when user has finished 
    /// editing/viewing the current cell
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void dataGridView1_CellValidating
        (object sender, DataGridViewCellValidatingEventArgs e) {

        DataGridViewComboBoxCell cell =
            dataGridView1.CurrentCell as DataGridViewComboBoxCell;
                
        if (cell != null && 
            !cell.Items.Contains(e.FormattedValue)) {
            
            // Insert the new value into position 0
            // in the item collection of the cell
            cell.Items.Insert(0, e.FormattedValue);
            // When setting the Value of the cell, the  
            // string is not shown until it has been
            // comitted. The code below will make sure 
            // it is committed directly.
            if (dataGridView1.IsCurrentCellDirty) {
                // Ensure the inserted value will 
                // be shown directly.
                // First tell the DataGridView to commit 
                // itself using the Commit context...
                dataGridView1.CommitEdit
                    (DataGridViewDataErrorContexts.Commit);
            }
            // ...then set the Value that needs 
            // to be committed in order to be displayed directly.
            cell.Value = cell.Items[0];
        }
    }


}
}

 

 

Regex Start | Regex Complex | Regex Replace | Front Page

Disclaimer

© Copyright 2003-2010 Sommergyll Software. All Rights Reserved.

Guide to Programming DataGridViewComboBoxCell in DataGridView