防止控件在禁用时变灰

在winforms .net控件中,如果我们将Enabled属性设置为false,则控件将显示为灰色。

在这种情况下,对于许多颜色组合,它将变得不可读(因为我提供了在运行时为用户更改表单颜色的选项)。

我可以使用ReadOnly属性,但它仅适用于TextBox控件,而不适用于其他控件,如ComboBox,DateTimePicker等。

我只是想知道是否有任何可用的选项,以便我可以防止控件在禁用时变灰。

在大多数可用性研究中,这是一个悲伤的时刻,看到主题在鼠标和键盘上敲打而不理解为什么它不起作用。 但如果你真的想要,你可以得到它。 诀窍是在控件前面放置一个图片框,显示控件在其先前启用状态下的位图。 他们永远不会发现他们点击位图而不是实际控件。

最好使用Panel,这样您就可以轻松地将控件作为一组禁用。 在项目中添加一个新类并粘贴下面显示的代码。 编译。 将新控件从工具箱顶部拖放到表单上。 并将控件放在其中应该被禁用。 其他一切都是自动的,只需将Enabled属性设置为false,用户就不会知道发生了什么:

using System; using System.Drawing; using System.Windows.Forms; class FakeItPanel : Panel { private PictureBox mFakeIt; public new bool Enabled { get { return base.Enabled; } set { if (value) { if (mFakeIt != null) mFakeIt.Dispose(); mFakeIt = null; } else { mFakeIt = new PictureBox(); mFakeIt.Size = this.Size; mFakeIt.Location = this.Location; var bmp = new Bitmap(this.Width, this.Height); this.DrawToBitmap(bmp, new Rectangle(Point.Empty, this.Size)); mFakeIt.Image = bmp; this.Parent.Controls.Add(mFakeIt); this.Parent.Controls.SetChildIndex(mFakeIt, 0); } base.Enabled = value; } } protected override void Dispose(bool disposing) { if (disposing && mFakeIt != null) mFakeIt.Dispose(); base.Dispose(disposing); } } 

实际上,您不希望修改禁用/启用控件的颜色行为。 当你有机会获得微软更新的Windows用户体验指南,因为它会为你的布局/设计提供一些指导,但如果这是你的应用程序必不可少的function,那么你需要自己处理控件绘制事件,或者inheritance并覆盖其绘制事件并自行绘制自定义颜色以完全控制此方面。

我个人的建议是找到另一种途径,正如其他人提到的那样,人们希望程序以特定的方式运行,但是如果你确实提供了配色方案function,可能会限制可以更改/个性化的应用程序部分。

我会想出你需要根据用户的访问权限将某些字段设置为只读。 这意味着具有编辑某些信息权限的用户可能会看到combobox,而不允许使用此权限的用户编辑该信息,但仍然可以查看该信息并可能需要查看该信息。

我建议您根据需要在屏幕上选择正确的控件。 如果用户可以更改combobox中的选定值,请显示combobox。 如果不允许用户更改该值,请显示包含所选值的只读文本框。

简化上述解决方案的一种方法是开发一些用户控件,根据属性调整他们显示数据的方式,让我们称之为Editable的控件。 因此,如果Editable为true,您可以创建一个显示combobox的用户控件,如果Editable为false,则可以创建一个文本框。 然后是datatimepicker等的相应控件。

如果您的程序中有“只读模式”,请将复选框,选项框,列表框和文本框作为标签。

例如,我做了一个在线测验,在输入值时,它内置了复选框等等,但当有人查看测验时,您会将所有答案视为标签,并将所选值作为文本。 对我来说,这是唯一的方法,不会干扰用户和开发人员的正常思维方式。

如果您有一组可选择的选项并希望即使在只读模式下也可以看到选项,那么请写出所有选项并以不像选项框och复选框的方式标记所选择的选项。

这是我在这方面的5美分。

我知道这是一个老线程,但我偶然发现了一个替代的简单解决方案。

创建一个inheritance自Label的新透明标签控件:

 class TransparentLabel : Label { public TransparentLabel() { this.SetStyle(ControlStyles.Opaque, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false); } protected override CreateParams CreateParams { get { CreateParams parms = base.CreateParams; parms.ExStyle |= 0x20; // Turn on WS_EX_TRANSPARENT return parms; } } } 

(我没有声称发明了这个课程,它来自其他地方,可能是Hans Passant :-))

在您的设计器中,创建一个TransparentLabel并为其命名,例如tLabel1 。 设置属性如下:

  • AutoSize – False,以便您可以展开它以涵盖要禁用的所有控件(当然可能是整个forms)。
  • Text – 空白。
  • Visible – 错误(或者如果您想在设计器中看到它,则保持为真,在这种情况下,将其移动到Z顺序的后面,这样您也可以看到它所涵盖的控件)。

在窗体中,当您要禁用控件时执行以下代码:

 tLabel1.Visible = true; tLabel1.BringToFront(); // if your designer has it at the back 

这是有效的,因为当它可见时,TransparentLabel会获得所有鼠标点击和按键而不是底层控件,但它是透明的,因此您仍然可以看到底层控件。 鼠标右键单击不执行任何操作,因为标签没有上下文菜单。

要重新启用控件,只需再次将Visible属性设置为false,一切都会恢复生机。