如何抑制用户对 ListBox 控件的操作

How to supress user actions on a ListBox control

假设我们有一个控件(例如 ListBox)并且需要锁定它以防止鼠标点击和键盘操作。当然,有一个标准属性Enabled,但它会导致外观变化,我的情况是不可取的。

我找到了一个使用 Windows API 的简单解决方案,请参见下文。令人惊讶的是,我没有找到完全适合我的任务的类似问题,所以让我与社区分享这个明显的解决方案。

欢迎任何补充和评论。以防有人提出更多 appropriate/shorter/nicer 答案。

我们可以使用 Windows API 来锁定我们对用户操作的控制。

首先我们应该找出哪些标准 WinAPI 消息在发送到控件时会被抑制。在我的 ListBox 控件的特殊情况下,我选择了 WM_LBUTTONDOWNWM_KEYDOWNWM_SETFOCUS 消息 (see docs),以锁定鼠标和键盘按钮按下并防止我的控件聚焦.

其次我们基于 ListBox 创建一个派生控件 class,为了方便,在相同的命名空间中:

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 标志状态停止发布所选消息。

第三,我们只是在表单 class 设计器部分需要的地方将 ListBox 更改为 LockableListBox

现在,当设置 Lock 属性 时,我们修改后的 ListBox 将免受用户操作(鼠标点击、键盘操作和聚焦)的影响。