【问题标题】:C#.NET Winform keypress event can't be cancelledC#.NET Winform 按键事件无法取消
【发布时间】:2015-03-07 13:37:30
【问题描述】:

我有一个带有 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。

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

【问题讨论】:

  • 您是否尝试禁用通过空格键检查复选框?
  • 你到底是什么意思?有那个属性吗?请记住,这是一个 DataGridViewCheckBox。
  • 我的意思是,你是想阻止DataGridViewCheckBox 按空格键检查吗?
  • 是的。为了清楚起见,编辑了问题。
  • 您正在与已经treats a space as special 的控件进行战斗。你赢不了,别费心了。

标签: c# .net winforms


【解决方案1】:

DataGridView.EditMode Property 怎么样

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

在哪里

默认为EditOnKeystrokeOrF2

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

您可以从DataGridViewEditMode Enumeration 中选择多个选项

  • EditOnEnter - 当单元格获得焦点时开始编辑。当按 TAB 键跨行输入值或按 ENTER 键向下输入值时,此模式很有用。

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

  • EditOnKeystroke - 在单元格获得焦点的情况下按下任意字母数字键时开始编辑。

  • EditOnKeystrokeOrF2 - 在单元格获得焦点时按下任意字母数字键或 F2 时开始编辑。

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


更新DataGridViewCheckBoxCell

事实证明DataGridViewEditMode 不适用于DataGridViewCheckBoxColumn

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

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);
        }
    }
}

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

【讨论】:

  • 我似乎可以用该属性完成的唯一一件事是防止任何类型的编辑,EditProgrammatically。除此之外,行为是相同的。
  • 我已经更新了我的答案。您可以尝试自定义单元格。我已经对其进行了测试,它对我有用。
【解决方案2】:

如果目标是在检查更改时始终立即做出反应,而不是阻止使用空格键(除非我弄错了,问题是 cellmouseup 方法不包括(取消)检查空格,而不是目标是根本不应该使用空间?),您可以使用 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);
                }
            }
        }

【讨论】:

  • 您对空格键的假设是正确的。下周回来上班,我会试试的。
【解决方案3】:

你可以覆盖FormProcessCmdKey方法:

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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2015-05-19
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    相关资源
    最近更新 更多