C#.NET Winform按键事件无法取消

时间:2015-01-09 09:09:04

标签: c# .net winforms

我有一个带有datagridview的(.NET 3.5)winform,我在网格视图中的复选框上添加了一个事件,如this。该帖子没有考虑到人们也可以使用空格键来切换复选框,并且由于没有CellKeyUp事件,例如有CellMouseUp事件,我启用了KeyPreview在窗体上添加此代码以防止切换到空格键:

private void BulkOrderAddressDifferencesForm_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Space)
    {
        e.Handled = true;
        e.SuppressKeyPress = true;
    }
}

这主要起作用,但是有一种情况仍然处理事件,即使调试器显示e.Handled设置为true。

Form with controls

如果我单击一个复选框,然后单击1,然后单击2,我可以再次使用空格键切换复选框。我不知道为什么会这样,我也不知道如何解决它。

3 个答案:

答案 0 :(得分:0)

DataGridView.EditMode Property

怎么样?
  

获取或设置一个值,指示如何开始编辑单元格。

其中

  

默认值为EditOnKeystrokeOrF2

  

DataGridViewEditMode之外的所有EditProgrammatically值都允许用户双击一个单元格以开始编辑它。

您可以从DataGridViewEditMode Enumeration

中选择多个选项
  • EditOnEnter - 当单元格获得焦点时开始编辑。当按TAB键在一行中输入值或按ENTER键在列中输入值时,此模式非常有用。

  • EditOnF2 - 在单元格有焦点时按F2键开始编辑。此模式将选择点放在单元格内容的末尾。

  • EditOnKeystroke - 在单元格有焦点时按任意字母数字键开始编辑。

  • EditOnKeystrokeOrF2 - 当单元格有焦点时,如果按下任何字母数字键或F2,则开始编辑。

  • EditProgrammatically - 仅在调用BeginEdit方法时才开始编辑。


DataGridViewCheckBoxCell

更新

事实证明DataGridViewEditModeDataGridViewCheckBoxColumn不起作用。

在这种情况下,您可以创建自己的DataGridViewCheckBoxColumn& DataGridViewCheckBoxCell。这允许您覆盖单元格的OnKeyUp事件处理程序,并在按下EditingCellFormattedValue时重置Space

public class MyCheckBoxColumn : DataGridViewCheckBoxColumn
{
    public MyCheckBoxColumn()
    {
        CellTemplate = new MyCheckBoxCell();
    }
}

public class MyCheckBoxCell : DataGridViewCheckBoxCell
{
    protected override void OnKeyUp(KeyEventArgs e, int rowIndex)
    {
        if (e.KeyCode == Keys.Space)
        {
            e.Handled = true;
            if (EditingCellValueChanged)
            {
                // Reset the value.
                EditingCellFormattedValue = !(bool)EditingCellFormattedValue;
            }
        }
        else
        {
            base.OnKeyUp(e, rowIndex);
        }
    }
}

重建项目后,新列应出现在设计器中:

enter image description here

答案 1 :(得分:0)

您可以覆盖Form' ProcessCmdKey方法:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.Space && checkBox1.Focused)
    {
        //instead of checkBox1.Focused condition, you check if your DataGridView contains focus and active cell is of checkBox type 
        return true;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

答案 2 :(得分:0)

如果目标是在检查更改时始终立即做出反应,而不是阻止使用空格键(除非我错了,问题是cellmouseup方法不包括(un)检查空间,而不是目标是不应该使用空间?),你可以使用celldirtychanged方法而不是cellmouseup来捕获它们

//grid.CurrentCellDirtyStateChanged += grid_CurrentCellDirtyStateChanged;

        void grid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            if (grid.IsCurrentCellDirty)
            {
                var cell = grid.CurrentCell;
                if (cell is DataGridViewCheckBoxCell)
                {
                    grid.EndEdit();
                    //you could catch the cellvaluechanged event (or a bound listchanged event), or handle the change immediately here, e.g.:
                    //Console.WriteLine("{0} value changed to {1}", cell.OwningColumn.HeaderText, cell.Value);
                }
            }
        }