首页 > 解决方案 > 是否可以禁用控件但仍接收该控件的事件?

问题描述

在 windows 窗体中,我有一个简单的文本框:

TextBox textBox = new TextBox() { Text = "text" };
textBox.Enabled = false;
textBox.MouseEnter += (object sender, EventArgs e) =>
{
    MessageBox.Show("MOUSE ENTERED"); // this never fires if the control is disabled.
};

我想禁用用户与控件交互的能力,并且希望将控件设置为禁用控件。但我也想从控件接收MouseEnterMouseLeaveClick事件,以便我可以在悬停时更改控件的背景封面并响应控件上的单击。

但是正如我刚刚发现的那样,如果您禁用 Windows 窗体控件,它也会禁用事件。我知道通过一些努力我可以通过全局检查鼠标坐标来完成同样的事情,但是如果我可以禁用它但仍然接收它的事件会更好。那可能吗?

标签: c#winforms

解决方案


Enabled在 Windows 窗体本身中并没有真正做任何事情。通常,禁用的窗口不接收输入消息(例如鼠标事件和键盘事件)是窗口控件的一个属性。所以不,您无法禁用控件并仍然收到这些消息。Windows 只是不能在 Windows 上以这种方式工作。不是TextBox控件过滤掉这些消息——它们不是一开始就出现的。

TextBox是一个很好的windows公共控件包装器。当您执行类似tbx.Text = "Hello";的操作时,TextBox只会向该公共控件发送一条消息,说“将文本更改为 Hello”。如果你想改变它,你需要从头开始制作控件。您可以进行一些技巧来恢复通用控件对鼠标事件的响应,但是这些通常不能很好地工作并且往往会以意想不到的方式发生故障。

在实践中,您真正想要的可能是调整ReadOnly行为方式(例如禁用焦点以及使控件只读,但这又只是一个肮脏的黑客),或者用TextBox可以是控件或控件的控件替换一个标签 - 允许您在两者之间切换。如果您希望文本框停止作为文本框,请停止将其作为文本框。问题解决了 :)

不过,我仍然会重新考虑使用ReadOnly。您确定用户不想在文本框中选择文本并将其复制到其他地方吗?或者改变阅读顺序?


推荐阅读