问题描述
假设我们有一个控件(例如ListBox),并且需要从鼠标单击和键盘操作中锁定它。当然,有一个标准属性Enabled
,但它会导致外观更改,这对我来说是不可取的。
我找到了使用Windows API的简单解决方案,请参见下文。出乎意料的是,我还没有找到适合自己任务的类似问题,所以让我与社区分享这个显而易见的解决方案。
任何补充和评论均表示赞赏。如果有人会提出更合适/更简短/更准确的答案。
解决方法
我们可以使用Windows API从用户操作中锁定控件。
首先,我们应该找出在发布到控件时将禁止使用哪些标准WinAPI消息。在ListBox控件的特殊情况下,我选择了WM_LBUTTONDOWN
,WM_KEYDOWN
和WM_SETFOCUS
消息(see docs),以锁定鼠标和键盘按钮的按下并防止控件集中
第二,为方便起见,我们在同一命名空间中基于ListBox
创建派生的控件类:
public class LockableListbox : ListBox
{
public bool Locked { get; set; }
const int WM_LBUTTONDOWN = 0x0201;
const int WM_SETFOCUS = 0x0007;
const int WM_KEYDOWN = 0x0100;
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand,Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
if (Locked)
switch (m.Msg)
{
case WM_LBUTTONDOWN:
case WM_KEYDOWN:
case WM_SETFOCUS:
return;
}
base.WndProc(ref m);
}
}
此处,控件的标准WndProc
方法已被覆盖,以根据Lock
标志状态阻止所选消息的发布。
第三,我们在需要的Form类设计器部分中将ListBox
更改为LockableListBox
。
现在,设置了Lock
属性后,我们修改后的ListBox将受到保护,免受用户操作(鼠标单击,键盘操作和对焦)。