【发布时间】:2010-09-13 02:06:34
【问题描述】:
是否存在DataGridViewCell 的Keydown 事件?
我想要做的是当用户在特定单元格中输入时,他可以按 F1 以获得该特定列的帮助。并且会弹出一些表单...
这是什么活动?
【问题讨论】:
标签: c# winforms datagridview
是否存在DataGridViewCell 的Keydown 事件?
我想要做的是当用户在特定单元格中输入时,他可以按 F1 以获得该特定列的帮助。并且会弹出一些表单...
这是什么活动?
【问题讨论】:
标签: c# winforms datagridview
我在论坛中找到了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");
}
}
【讨论】:
DataGridViewCell 没有任何事件,但是您可以在DataGridView 本身上监听KeyDown 事件,然后查看选择了哪个单元格:
public void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F1)
{
var selectedCell = dataGridView.SelectedCells[0];
// do something with selectedCell...
}
}
【讨论】:
当用户在单元格中键入时,实际上是在为编辑目的而放置在单元格内的控件中键入。例如,字符串列类型实际上会创建一个 TextBox 以在单元格内使用,供用户输入。因此,在进行编辑时,您需要真正挂钩放置在单元格内的 TextBox 的 KeyDown 事件。
【讨论】:
另一种解决方案是
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;
}
}
}
【讨论】:
我知道这是一个老问题,但我相信我在投票最多的答案上有所改进。
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 事件,并且您的事件不仅限于一种类型的单元格。
【讨论】:
这段代码对我有用。
Form.KeyPreview = true;
Microsoft Docs 中的描述:“...(KeyPreview) 设置一个值,指示在将事件传递给具有焦点的控件之前表单是否会接收键事件。”。
【讨论】:
覆盖 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
}
【讨论】:
在您的解决方案中,您不应忘记取消监听事件
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
tb.KeyUp -= Tb_KeyUp;
}
在我的解决方案中,我订阅了 KeyUp,而不是 KeyDown,因为我需要替换编辑单元格的值
DataGridViewTextBoxEditingControl tb { get; set; }
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
tb = (DataGridViewTextBoxEditingControl)e.Control;
CellEditingTB.KeyUp += Tb_KeyUp;
}
private void Tb_KeyUp(object sender, KeyEventArgs e)
{
if (tb != null)
{
if (e.KeyCode == Keys.Decimal)
{
..
}
}
}
【讨论】: