How do I get DataGridView comboboxes to display th

2020-03-03 07:33发布

问题:

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.

回答1:

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.



回答2:

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


回答3:

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


回答4:

see: VB.NET Controls inside of a DataGridView Row on a Windows Form



回答5:

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.