5

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.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Isaac Bolinger
  • 7,328
  • 11
  • 52
  • 90

4 Answers4

6

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.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • I've already got lots of 'hacks' in that datagridview class of mine. One more isn't going to hurt. I'll try this out today. – Isaac Bolinger Nov 28 '10 at 17:07
  • I just hope this someday doesn't get in the way of my plan to use the F-Keys to switch between tabs. – Isaac Bolinger Nov 28 '10 at 18:35
  • @IsaacB: You'll have to be careful using F-Keys to switch between tabs either way. Certain F-Keys have pre-defined uses in Windows that you probably shouldn't override. Like the above demonstrates, whenever any combo box has focus, F4 will cause it to drop down. F10 always activates the application's menu system. – Cody Gray - on strike Nov 29 '10 at 03:53
  • Thanks for the warning. I'm pretty green at all of this. – Isaac Bolinger Nov 29 '10 at 05:07
  • This isn't really the whole solution, if on editing control showing will fire in times other than when they click on the box, such as if you click on another tab in the tab control and click back to the original tab, or sort the dgv when the combobox is the first column in the list etc. It just opened up a bigger can of worms. – Isaac Bolinger Dec 03 '10 at 22:15
  • Unfortunately, the cellclick event doesn't fire very reliably when clicking on comboboxes either :( – Isaac Bolinger Dec 03 '10 at 22:27
  • @IsaacB: I suppose that's true. There are cases where this behavior might not be appropriate, but you're trying to do something non-standard: Combo boxes are not designed to drop down when they get the focus. And with the territory comes some tradeoffs and unexpected behaviors. I assume the reason the `CellClick` event doesn't work is it only fires when the cell is...clicked, not when it gets the focus using the tab key. – Cody Gray - on strike Dec 04 '10 at 07:11
  • I'm still using this trick though, I'm just adding little hacks to fix the unexpected behaviors as they arise. I guess that's the nature of the datagridview... – Isaac Bolinger Dec 10 '10 at 20:29
4

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);
}
System.Cats.Lol
  • 1,620
  • 1
  • 26
  • 47
1
    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;
        }
    }
0

To avoid the SendKeys issues, try the solution from Open dropdown(in a datagrid view) items on a single click. Essentially, in OnEditingControlShowing hook to the Enter event of the combo box, in the Enter event handler, set ComboBox.DroppedDown = true. That seems to have the same effect, but without the side effects @Cody Gray mentions.

Community
  • 1
  • 1
Steven Bone
  • 588
  • 5
  • 16