Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get DataGridView comboboxes to display their drop down list in one click?

After I set "EditOnEnter" to be true, the DataGridViewComboBoxCell still takes two clicks to open if I don't click on the down arrow part of the combo box.

Anyone have any clue how to fix this? I've got my own DataGridView class that I use, so I can easily fix this issue system-wide with a few smart event handlers I hope.

Thanks.

like image 878
Isaac Bolinger Avatar asked Nov 28 '10 07:11

Isaac Bolinger


3 Answers

Since you already have the DataGridView's EditMode property set to "EditOnEnter", you can just override its OnEditingControlShowing method to make sure the drop-down list is shown as soon as a combo box receives focus:

public class myDataGridView : DataGridView
{

    protected override void OnEditingControlShowing(DataGridViewEditingControlShowingEventArgs e)
    {
        base.OnEditingControlShowing(e);

        if (e.Control is ComboBox) {
            SendKeys.Send("{F4}");
        }
    }

}

Whenever an edit control in your DataGridView control gets the input focus, the above code checks to see if it is a combo box. If so, it virtually "presses" the F4 key, which causes the drop-down portion to expand (try it when any combo box has the focus!). It's a little bit of a hack, but it works like a charm.

like image 143
Cody Gray Avatar answered Nov 14 '22 21:11

Cody Gray


I used this solution as it avoids sending keystrokes:

Override the OnCellClick method (if you're subclassing) or subscribe to the CellClick event (if you're altering the DGV from another object rather than as a subclass).

protected override void OnCellClick(DataGridViewCellEventArgs e)
{
    // Normally the user would need to click a combo box cell once to 
    // activate it and then again to drop the list down--this is annoying for 
    // our purposes so let the user activate the drop-down with a single click.
    if (e.ColumnIndex == this.Columns["YourDropDownColumnName"].Index
        && e.RowIndex >= 0
        && e.RowIndex <= this.Rows.Count)
    {
        this.CurrentCell = this[e.ColumnIndex, e.RowIndex];
        this.BeginEdit(false);
        ComboBox comboBox = this.EditingControl as ComboBox;
        if (comboBox != null)
        {
            comboBox.DroppedDown = true;
        }
    }

    base.OnCellContentClick(e);
}
like image 39
System.Cats.Lol Avatar answered Nov 14 '22 22:11

System.Cats.Lol


    protected override void OnEditingControlShowing(DataGridViewEditingControlShowingEventArgs e)
    {
        base.OnEditingControlShowing(e);
        DataGridViewComboBoxEditingControl dataGridViewComboBoxEditingControl = e.Control as DataGridViewComboBoxEditingControl;
        if (dataGridViewComboBoxEditingControl != null)
        {
            dataGridViewComboBoxEditingControl.GotFocus += this.DataGridViewComboBoxEditingControl_GotFocus;
            dataGridViewComboBoxEditingControl.Disposed += this.DataGridViewComboBoxEditingControl_Disposed;
        }
    }

    private void DataGridViewComboBoxEditingControl_GotFocus(object sender, EventArgs e)
    {
        ComboBox comboBox = sender as ComboBox;
        if (comboBox != null)
        {
            if (!comboBox.DroppedDown)
            {
                comboBox.DroppedDown = true;
            }
        }
    }

    private void DataGridViewComboBoxEditingControl_Disposed(object sender, EventArgs e)
    {
        Control control = sender as Control;
        if (control != null)
        {
            control.GotFocus -= this.DataGridViewComboBoxEditingControl_GotFocus;
            control.Disposed -= this.DataGridViewComboBoxEditingControl_Disposed;
        }
    }
like image 39
user3342263 Avatar answered Nov 14 '22 22:11

user3342263