C#按键事件无法捕获“删除”键

42

我在一个ListView上添加了一个keyPress事件。 我在事件上设置了断点,可以看到大多数按键都会触发该事件。 但是,其中一些键,包括我感兴趣的键(删除键),就是无法触发我的事件。

这很奇怪吗?不,我的键盘上没有损坏的键:D

    private void listView1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar == (char)Keys.Delete)
        {
            ListView target = (ListView)sender;
            if (target.SelectedIndices != null && target.SelectedIndices.Count > 0)
            {
                string ric = target.SelectedItems[0].SubItems[0].Text;
                //target.Items.RemoveAt(target.SelectedIndices[0]);
                ListModels.getInstance().getModel("Vols").removeRic(ric);
            }
        }
    }

1
请问您能否包含您正在使用的代码? - Ryan Berger
1
可能是向下箭头不触发KeyPress事件的重复问题。 - Austin Salonen
1
这并不完全相同,但是我的重复建议中的答案回答了这个问题。 - Austin Salonen
8个回答

54
这是因为KeyPress事件会根据你按下的字符键向控件发送字符。但是,正如你所预料的那样,删除键并不代表一个字符,因此它是一个非字符键。
因此,使用KeyPress事件将没有任何作用,正如你所注意到的。你应该使用KeyDown或KeyUp事件,两者都可以完美地工作。区别在于你是否想在按下键时触发事件,还是在松开键时触发事件。

2
你写道:“正如你所预期的那样,删除键并不代表一个字符。”或许你可以详细说明一下删除键不是一个字符,因为如果你查看ASCII表,字符8是后退删除字符,字符127是DEL(无疑是向前删除)字符。而且如果我们谈论扫描码,https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html中列出了一个小键盘删除键。 - barlop
当然可以!更明确地说,删除键是一个非字符键,因此在按下诸如“A”等字符键时,KeyPress事件不会触发,因为它会向控件发送一个字符。如果删除键是一个字符键,那么KeyPress事件就会完美触发。我还会将这个内容添加到我的答案中以供进一步阅读。 - Bradley
你应该非常明确地说明你的答案并声明它是根据.NET框架或MSDN文档的术语,要成为一个字符,它必须是可打印的,因此在MSDN/.NET术语中,删除不是一个字符。(与古典术语相反,删除符一定是一个字符)。 - barlop
1
你只是在以不同的方式重复自己,我不确定你在这里的意图是什么。除非有明确要求,否则没有必要澄清;如果您每次使用约定时都必须明确地描述为什么使用它们,那么它们将完全不实用。该环境中的惯例是将ASCII控制字符称为非字符键,对于不知道特定语言或环境惯例的人来说,理解为什么以某种方式引用事物是由他们自己承担责任,可以通过询问或进行必要的研究来了解。 - Bradley
似乎存在一些边缘情况,例如 Unicode 删除 '\u007f',如果按下 Ctrl + Backspace,则会在 KeyPress 中显示。 - Raphael Smit
显示剩余5条评论

5
在KeyDown中使用以下条件:
if (e.KeyCode == Keys.Delete)
{
   // Your Logic....
}

5
您需要使用 KeyDown 事件来实现此功能。

4
请使用 keyDown 代替; keyPress 类似于完整的 keyDown + keyUp

1
问题在于,如果您将 EditMode 属性设置为 EditOnEnter,则不会触发事件。如果使用 EditOnKeyStrokeOfF2,则会触发该事件。

0
如果您正在寻找一种解决方案,使用户只能从定义的项目中选择,那么我相信您可以使用以下方法实现:
  private void DropDownRank_KeyDown(object sender, KeyEventArgs e)
    {
        e.SuppressKeyPress = true;
    }

0
请看这段代码:
private void Form1_Load(object sender, EventArgs e)
{
    listView1.KeyUp += new KeyEventHandler(ListView_KeyUp);
}

/// <summary>鍵盤觸發 ListView 清單</summary>
private void ListView_KeyUp(object sender, KeyEventArgs e)
{
    ListView ListViewControl = sender as ListView;
    if (e.KeyCode == Keys.Delete)
    {
        foreach (ListViewItem eachItem in ListViewControl.SelectedItems)
        {
            ListViewControl.Items.Remove(eachItem);
        }

    }
}

0
我尝试了以上提到的所有方法,但都没有效果,所以我在这里发布我实际操作并有效的内容,希望能帮助其他遇到同样问题的人:
在构造函数中添加事件处理程序:

public partial class Test
    {
    public Test()
        {
            this.RemoveHandler(KeyDownEvent, new KeyEventHandler(Test_KeyDown)); 
            // im not sure if the above line is needed (or if the GC takes care of it
            // anyway) , im adding it just to be safe  
            this.AddHandler(KeyDownEvent, new KeyEventHandler(Test_KeyDown), true);
            InitializeComponent();
        }
     //....
      private void Test_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                //your logic
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接