Prevent controls from graying out when it is disabled
In winforms .net controls if we set Enabled property to false the control will be grayed out.
In this case it will become unreadable for many color combinations (because i am giving options to change color of a form for user at run time).
I can use ReadOnly property but it is available only to TextBox controls not for other controls like ComboBox, DateTimePicker etc.
I just wanted to know is there any option available so that i can prevent controls from graying out when i开发者_运维问答t is disabled.
This is a sad moment in most any usability study, seeing the subject banging away at the mouse and keyboard and not understanding why it doesn't work. But you can get it if you really want to. The trick is to put a picture box in front of the control that shows a bitmap of the controls in their previously enabled state. They'll never figure out they are clicking on a bitmap instead of the actual controls.
Best done with a Panel so you can easily disable controls as a group. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form. And put the controls inside it that should be disabled. Everything else is automatic, just set the Enabled property to false and the user won't know what happened:
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);
}
}
I know this is an old thread but I have discovered an alternative simple solution by accident.
Create a new transparent label control that inherits from 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;
}
}
}
(I don't claim to have invented this class, it came from somewhere else, probably Hans Passant :-) )
In your designer, create a TransparentLabel and give it a name, say tLabel1
. Set properties as follows:
AutoSize
- False so that you can then expand it to cover all the controls you want to disable (which might be the whole form of course).Text
- blank.Visible
- False (or leave it true if you want to see it in the designer, in which case move it to the back of the Z order so you can also see the controls it will cover when the form runs).
In the Form, execute this bit of code when you want to disable the controls:
tLabel1.Visible = true;
tLabel1.BringToFront(); // if your designer has it at the back
This works because when it is visible the TransparentLabel is getting all the mouse clicks and key presses rather than the underlying control, but it is transparent so you still see the underlying controls. Mouse right-click does nothing because labels do not have a context menu.
To re-enable the controls, just set the Visible property false again and everything springs back into life.
I will go out on a limb and guess that you need to make certain fields read-only based on the user's access rights. Meaning that a user with right to edit certain information might see the combobox while a user laking this right would not be allowed to edit the information but can still view it and possibly needs to view it.
I would suggest that you have the screen select the right control based on the requirement. If the user can change the selected value in a combobox, show the combobox. If the user should not be allowed to change the value, show a readonly textbox which contains the selected value.
One way to simplify the above solution is to develop some user controls that adjust the way they display the data according to a propery, lets call it Editable
, of the control. So you can create a user control which shows a combobox if Editable
is true and a textbox if Editable
is false. And then a corresponding control for the datatimepicker etc.
Realistically you do not want to modify the color behaviours of disable/enable controls. Hit up Microsoft's updated Windows UX Guidelines when you get a chance as it will give you some guidance to layout/design, but if this is a absolutely must feature for your application then you will need to either handle the controls paint event yourself, or inherit and override its paint event and draw the custom colors on your own to control this aspect completely.
My personal recommendation would to be find another avenue, as others have mentioned people expect programs to behave a specific way, however if you do provide color scheme features, maybe limit the parts of the application that can be changed/personalized.
If you have a "read only mode" in your program, make checkboxes, optionboxes, listboxes and textboxes as labels.
I have for example done an online quiz that when entering values, its built of checkboxes and so on, but when someone review the quiz you see all answers as labels with the selected value as text. For me this is the only way to do it without disturbing the normal way of thinking UI both for the user and developer.
If you have a group of selectable choices and want the choices to be visible even in the read only mode, then write out all choices and mark out the selected one in a way that does not look like a optionbox och checkbox.
Thats my 5 cents in this area.
精彩评论