如何处理DataGridView单元中的关键事件?

时间:2010-09-13 02:06:34

标签: c# winforms datagridview

Keydown是否有DataGridViewCell事件? 我想要做的是当用户在特定单元格中键入内容时,他可以按F1获取该特定列的帮助。一些表格会弹出......

它是什么事件?

7 个答案:

答案 0 :(得分:18)

我在论坛中找到了this代码,但它确实有效。

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
  DataGridViewTextBoxEditingControl tb =(DataGridViewTextBoxEditingControl)e.Control;
  tb.KeyPress += new KeyPressEventHandler(dataGridViewTextBox_KeyPress);

  e.Control.KeyPress += new KeyPressEventHandler(dataGridViewTextBox_KeyPress);
}


private void dataGridViewTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
  //when i press enter,bellow code never run?
  if (e.KeyChar==(char)Keys.Enter)
  {
    MessageBox.Show("You press Enter");
  }
}

答案 1 :(得分:4)

DataGridViewCell没有任何事件,但您可以在KeyDown本身上侦听DataGridView事件,然后查看选择了哪个单元格:

public void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.F1)
    {
        var selectedCell = dataGridView.SelectedCells[0];
        // do something with selectedCell...
    }
}

答案 2 :(得分:3)

当用户键入单元格时,它实际上正在键入放置在单元格内的控件以进行编辑。例如,字符串列类型实际上将创建一个TextBox,以便在单元格内部供用户输入。因此,您需要实际挂接到编辑发生时放置在单元格内的TextBox的KeyDown事件。

答案 3 :(得分:1)

我知道这是一个老问题,但我相信我已经改进了最高投票的答案。

    IDataGridViewEditingControl _iDataGridViewEditingControl;
    private void SlotTimesDGV_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        if (_iDataGridViewEditingControl is DataGridViewComboBoxEditingControl)
        {
            DataGridViewComboBoxEditingControl iDataGridViewEditingControl = _iDataGridViewEditingControl as DataGridViewComboBoxEditingControl;
            iDataGridViewEditingControl.KeyPress -= SlotTimesDGV_EditingControlShowing_KeyPress;
        }
        if (e.Control is DataGridViewComboBoxEditingControl)
        {
            DataGridViewComboBoxEditingControl iDataGridViewEditingControl = e.Control as DataGridViewComboBoxEditingControl;
            iDataGridViewEditingControl.KeyPress += SlotTimesDGV_EditingControlShowing_KeyPress;
            _iDataGridViewEditingControl = iDataGridViewEditingControl;
        }
    }

    private void SlotTimesDGV_EditingControlShowing_KeyPress(object sender, KeyPressEventArgs e)
    {
        MessageBox.Show("");
    }

通过拥有IDataGridViewEditingControl的实例变量,您可以移除KeyPress事件,该事件在移动单元格时会导致重复调用,并且您的事件不仅限于一种类型的单元格。

答案 4 :(得分:0)

另一种解决方案是

private void grdDetalle_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        // Sólo queremos esta funcionalidad para determinadas columnas Clave y Nombre
        if ((grdDetalle.Columns[grdDetalle.CurrentCell.ColumnIndex].Name == "colClaveArticulo") ||
            (grdDetalle.Columns[grdDetalle.CurrentCell.ColumnIndex].Name == "colNombre"))
        {
            /// Workarround para que estando editando en las columnas del grid Clave y Nombre
            /// podamos detectar cuando se dio F4 para lanzar el dialogo de busqueda del
            /// articulo.
            e.Control.KeyDown += new KeyEventHandler(dataGridViewTextBox_KeyDown);
            e.Control.Leave += new EventHandler(dataGridViewTextBox_Leave);
        }
    }

    private void dataGridViewTextBox_Leave(object sender, EventArgs e)
    {

        if ((grdDetalle.Columns[grdDetalle.CurrentCell.ColumnIndex].Name == "colClaveArticulo") ||
           (grdDetalle.Columns[grdDetalle.CurrentCell.ColumnIndex].Name == "colNombre"))
        {
            try
            {
                (sender as DataGridViewTextBoxEditingControl).KeyDown -= 
                   new KeyEventHandler(dataGridViewTextBox_KeyDown);
            }
            catch (Exception ex)
            { }
        }
    }

    private void dataGridViewTextBox_KeyDown(object sender, KeyEventArgs e)
    {
        // F4 Pressed
        if ((grdDetalle.Columns[grdDetalle.CurrentCell.ColumnIndex].Name == "colClaveArticulo") ||
           (grdDetalle.Columns[grdDetalle.CurrentCell.ColumnIndex].Name == "colNombre"))
        {
            if (e.KeyCode == Keys.F4) // 115
            {
                MessageBox.Show("Oprimieron F4");
                e.Handled = true;
                e.SuppressKeyPress = true;
            }
        }
    }

答案 5 :(得分:0)

此代码确实对我有用。

Form.KeyPreview = true;

Microsoft Docs中的描述:“ ...(KeyPreview)设置一个值,该值指示在将事件传递给具有焦点的控件之前,表单是否将接收键事件。”

答案 6 :(得分:0)

覆盖类 Form 的虚函数 ProcessCmdKey 对我有用。

在 ProcessCmdKey 上返回 true 以防止进一步处理按键。 覆盖所有关键操作的函数

例如:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) //overridden virtual function
{
    if (keyData == Keys.Tab) //check to make sure it is the key I am interested in
    { 
        if (this.dataGridViewKeys.ContainsFocus) //make sure it is on the control, or any child controls, of the one I am interested in
        {
            this.dataGridViewKeys.EndEdit(); //do whatever action you want here
            if (this.dataGridViewKeys.CurrentRow.IsNewRow && this.dataGridViewKeys.Rows.Count > 1)
                this.dataGridViewKeys.CurrentCell = this.dataGridViewKeys.Rows[this.dataGridViewKeys.Rows.Count - 1].Cells[2];
            this.txtNoteData.Focus();
            return true;  //I return true to prevent further handling of the keypress
        }
    }
    return base.ProcessCmdKey(ref msg, keyData); //return this for keys you do not want to intercept
}