在 C# Win-Forms 的 ListView 项目编辑中没有击中 KeyEvent
No KeyEvent is hitting in ListView Item Edit in C# Win-Forms
我正在开发一个 Win-Forms 应用程序,有一个显示了一些项目的列表视图,需要编辑项目的标签。
所以启用 LabelEdit
属性 为真,并调用
listView1.SelectedItems[0].BeginEdit();
单击上下文菜单项。一切正常。
现在我需要验证用户在项目名称中输入的字符,
比如名字中不允许有特殊字符,所以在列表视图中注册了keyDown event
,但是在标签编辑模式下没有被击中,我尝试了所有其他按键事件,但是none被击中了。
一种解决方案是在
中进行验证
private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
// Validation code goes here
}
但我不想这样做,我想在用户输入无效字符时显示工具提示
谁能告诉我使用哪个事件??
如有任何帮助,我们将不胜感激。
你试过 Form.KeyPreview 了吗?
https://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview(v=vs.100).aspx
你可以设置一个 bool 变量来知道你正在编辑标签,当它是真的时,你继续对 Form.Keydown
执行验证
ListView 在用户开始编辑标签时动态创建一个 TextBox 控件。此控件未被 Winforms 包装,并且不与 OnBefore/AfterLabelEdit 事件之外的父事件交互。
这可以解决。 LVM_GETEDITCONTROL 消息允许您获取该文本框的句柄。然后 NativeWindow class 可以子 class 控件,这样您就可以拦截它的消息。点赞你感兴趣的键盘留言。
这里有一个例子,它将LabelKeyPress事件添加到ListView。您可以为其编写事件处理程序并将 e.Handled 属性 设置为 true 以防止使用按键。向您的项目添加一个新的 class 并粘贴下面的代码。编译。从工具箱顶部拖放新控件,替换原来的 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);
}
我正在开发一个 Win-Forms 应用程序,有一个显示了一些项目的列表视图,需要编辑项目的标签。
所以启用 LabelEdit
属性 为真,并调用
listView1.SelectedItems[0].BeginEdit();
单击上下文菜单项。一切正常。
现在我需要验证用户在项目名称中输入的字符,
比如名字中不允许有特殊字符,所以在列表视图中注册了keyDown event
,但是在标签编辑模式下没有被击中,我尝试了所有其他按键事件,但是none被击中了。
一种解决方案是在
中进行验证private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
// Validation code goes here
}
但我不想这样做,我想在用户输入无效字符时显示工具提示
谁能告诉我使用哪个事件?? 如有任何帮助,我们将不胜感激。
你试过 Form.KeyPreview 了吗? https://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview(v=vs.100).aspx
你可以设置一个 bool 变量来知道你正在编辑标签,当它是真的时,你继续对 Form.Keydown
执行验证ListView 在用户开始编辑标签时动态创建一个 TextBox 控件。此控件未被 Winforms 包装,并且不与 OnBefore/AfterLabelEdit 事件之外的父事件交互。
这可以解决。 LVM_GETEDITCONTROL 消息允许您获取该文本框的句柄。然后 NativeWindow class 可以子 class 控件,这样您就可以拦截它的消息。点赞你感兴趣的键盘留言。
这里有一个例子,它将LabelKeyPress事件添加到ListView。您可以为其编写事件处理程序并将 e.Handled 属性 设置为 true 以防止使用按键。向您的项目添加一个新的 class 并粘贴下面的代码。编译。从工具箱顶部拖放新控件,替换原来的 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);
}