将事件附加到DataGridView单元格的TextBox底层

Ran*_*dom 4 c# .net-2.0 winforms

有没有办法获得DataGridView单元的底层控件?我想附加普通的texbox事件来捕获击键并捕获更改的值.

所以我有4列,每列包含多个单元格,一行中的所有单元格应根据其类型以不同的方式处理.

基本上我只需要在编辑单元格时触发我的事件.

dig*_*All 9

订阅DataGridView.EditingControlShowing活动,然后订阅TextBox您需要的活动.


示例TextBox.KeyDown:

void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    var txtBox = e.Control as TextBox;
    if (txtBox != null)
    {
        // Remove an existing event-handler, if present, to avoid 
        // adding multiple handlers when the editing control is reused.
        txtBox.KeyDown -= new KeyEventHandler(underlyingTextBox_KeyDown);

        // Add the event handler. 
        txtBox.KeyDown += new KeyEventHandler(underlyingTextBox_KeyDown);
    }
}

void underlyingTextBox_KeyDown(object sender, KeyEventArgs e)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

编辑:

现在代码更正确,因为它遵循MSDN上给出的建议:

DataGridView控件一次承载一个编辑控件,并且只要单元格类型在编辑之间不发生更改,就会重新使用编辑控件.将事件处理程序附加到编辑控件时,必须采取预防措施以避免多次连接相同的处理程序.要避免此问题,请在将处理程序附加到事件之前从事件中删除处理程序.如果处理程序已附加到事件,这将防止重复,否则将无效.有关更多信息,请参阅DataGridViewComboBoxEditingControl类概述中的示例代码.

编辑2:

根据评论:

TextChanged事件在之前调用EditingControlShowing,然后在之后再调用.

您可以使用此技巧区分两个调用:

void txtBox_TextChanged(object sender, EventArgs e)
{
    var txtBox = (TextBox)sender;
    if (txtBox.Focused)
    {
        // second call (after EditingControlShowing) the TextBox is focused
    }
    else
    {
        // first call (before EditingControlShowing) the TextBox is not focused
    }
}
Run Code Online (Sandbox Code Playgroud)