处理自定义 DataGridView 列类型的键盘事件

Handling keyboard events for custom DataGridView column type

在下面的代码中,我扩展了 class DataGridViewTextBoxCell 以控制用户将在此字段中输入的值,为此我需要捕获事件 KeyDown。但是只有当我使用键盘在 DGV 中导航时才会调用该事件。当我编辑单元格的值时,事件不会发生。我的代码中缺少什么?

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DataGridView dataGridView = new DataGridView();

            MyDataGridViewColumn col = new MyDataGridViewColumn();
            dataGridView.Columns.Add(col);
            dataGridView.Rows.Add(new string[] { "0" });
            dataGridView.Rows.Add(new string[] { "1" });
            dataGridView.Rows.Add(new string[] { "2" });
            dataGridView.Rows.Add(new string[] { "3" });

            this.panel1.Controls.Add(dataGridView);
        }
    }

    public class MyDataGridViewColumn : DataGridViewColumn
    {
        public MyDataGridViewColumn()
        {
            this.CellTemplate = new MyDataGridViewTextBoxCell();
        }
    }

    public class MyDataGridViewTextBoxCell : DataGridViewTextBoxCell
    {
        protected override void OnKeyDown(KeyEventArgs e, int rowIndex)
        {
            base.OnKeyDown(e, rowIndex);

            var key = e.KeyCode;
        }
    }

这些击键将由编辑控件处理。如果您想为此目的创建自己的自定义列类型,那么您可以这样做:

  1. 通过派生自 DataGridViewTextBoxEditingControl 创建您的编辑控件。然后覆盖 OnKeyDown 并在那里添加你的逻辑。
  2. 通过派生自您在上一步中创建的 MyDataGridViewTextBoxCell. Then override EditType 和 return 类型的编辑控件来创建您的单元格。
  3. 最后,通过从 DataGridViewTextBoxColumn and in the constructor, set an instance of the cell that you created in the previous step, as its CellTemplate 派生来创建您的列。

例子

public class MyDataGridViewTextBoxColumn : DataGridViewTextBoxColumn
{
    public MyDataGridViewTextBoxColumn()
    {
        CellTemplate = new MyDataGridCViewTextBoxCell();
    }
}
public class MyDataGridCViewTextBoxCell : DataGridViewTextBoxCell
{
    public override Type EditType => typeof(MyDataGridViewTextBoxEditingControl);
}
public class MyDataGridViewTextBoxEditingControl : DataGridViewTextBoxEditingControl
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        //Put the logic here
    }
}

注1:对于不需要新建列类型的情况,可以轻松处理EditingControlShowing event of the DataGridView and check if the event belongs to your desired column, then get the editing control (and cast it to the right type), and then handle the proper event of the editing control, for example you can take a look at first code block in .

注意 2: 如果您有兴趣向 column/cell 添加自定义属性并在编辑控件中使用它们,您可以找到逐步的答案,包括post:

中的示例代码