在C#Win Forms中的ListView项编辑中没有出现KeyEvent

在C#Win Forms中的ListView项编辑中没有出现KeyEvent,c#,winforms,listview,event-handling,keyboard-events,C#,Winforms,Listview,Event Handling,Keyboard Events,我正在开发一个Win Forms应用程序,有一个显示了一些项目的列表视图,需要编辑项目的标签。 因此,已将LabelEdit属性启用为true,并调用 listView1.SelectedItems[0].BeginEdit(); 在关联菜单项上单击。很好用 现在我需要验证用户在item name中输入的字符, 像不允许在名称中使用特殊字符一样,因此在列表视图中注册了keyDown事件,但在标签编辑模式下没有命中,我尝试了所有其他键事件,但没有一个被命中 一种解决方案是在中进行验证 priva

我正在开发一个Win Forms应用程序,有一个显示了一些项目的列表视图,需要编辑项目的标签。 因此,已将
LabelEdit
属性启用为true,并调用

listView1.SelectedItems[0].BeginEdit();
在关联菜单项上单击。很好用

现在我需要验证用户在item name中输入的字符, 像不允许在名称中使用特殊字符一样,因此在列表视图中注册了
keyDown事件
,但在标签编辑模式下没有命中,我尝试了所有其他键事件,但没有一个被命中

一种解决方案是在中进行验证

private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
    // Validation code goes here
}
但我不想这样做,我想在用户输入无效字符时显示一个工具提示

有人能说出要使用哪个事件吗??
欢迎提供任何帮助。

您是否尝试过Form.KeyPreview?


您可以设置一个bool变量,以知道您正在编辑标签,如果该变量为真,您将继续对表单执行验证。当用户开始编辑标签时,Keydown

ListView会动态创建一个TextBox控件。此控件不由Winforms包装,并且不与OnBefore/AfterLabelEdit事件之外的其父级事件交互

这是可以解决的。LVM_GETEDITCONTROL消息允许您获取该文本框的句柄。然后,NativeWindow类可以对控件进行子类化,以便您可以截获其消息。喜欢你感兴趣的键盘信息

下面是一个示例,它将LabelKeyPress事件添加到ListView。您可以为它编写一个事件处理程序,并将e.Handled属性设置为true,以防止按键被使用。向项目中添加一个新类并粘贴下面的代码。编译。从工具箱顶部删除新控件,替换原始ListView

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class ListViewEx : ListView {
    public event KeyEventHandler LabelKeyDown = delegate { };
    public event KeyEventHandler LabelKeyUp = delegate { };
    public event KeyPressEventHandler LabelKeyPress = delegate { };
    private LabelTextBox Label;

    public ListViewEx() {
        Label = new LabelTextBox(this);
    }
    protected void OnLabelKeyDown(KeyEventArgs e) { LabelKeyDown(this, e); }
    protected void OnLabelKeyUp(KeyEventArgs e) { LabelKeyUp(this, e); }
    protected void OnLabelKeyPress(KeyPressEventArgs e) { LabelKeyPress(this, e); }

    protected override void OnBeforeLabelEdit(LabelEditEventArgs e) {
        const int LVM_GETEDITCONTROL = 0x1000 + 24;
        var hdl = SendMessage(this.Handle, LVM_GETEDITCONTROL, IntPtr.Zero, IntPtr.Zero);
        Label.AssignHandle(hdl);
        base.OnBeforeLabelEdit(e);
    }
    protected override void OnAfterLabelEdit(LabelEditEventArgs e) {
        Label.ReleaseHandle();
        base.OnAfterLabelEdit(e);
    }

    private class LabelTextBox : NativeWindow {
        private ListViewEx Parent;
        public LabelTextBox(ListViewEx parent) { this.Parent = parent; }

        protected override void WndProc(ref Message m) {
            switch (m.Msg) {
                case 0x100:
                    var args = new KeyEventArgs((Keys)m.WParam.ToInt32());
                    Parent.OnLabelKeyDown(args);
                    if (args.Handled) return;
                    break;
                case 0x101:
                    var args2 = new KeyEventArgs((Keys)m.WParam.ToInt32());
                    Parent.OnLabelKeyUp(args2);
                    break;
                case 0x102:
                    var args3 = new KeyPressEventArgs((char)m.WParam.ToInt32());
                    Parent.OnLabelKeyPress(args3);
                    if (args3.Handled) return;
                    break;
            }
            base.WndProc(ref m);
        }
    }

    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}