I have a custom control I am working on. I want to change its color when it is enabled or disabled. So I wrote a code inside OnEnabledChanged.
protected override void OnEnabledChanged(EventArgs e)
{
if (!Enabled)
{
temp1 = colorOn;
temp2 = colorOff;
colorOff = colorOn = Color.LightGray;
}
else
{
colorOn = temp1;
colorOff = temp2;
}
Invalidate();
base.OnEnabledChanged(e);
}
This code works fine in runtime but not design time. It wasn't raised when I changed the Enabled property in design time. So I want to override the Enabled property of the control. But it doesn't show up when typing it.
So how can I override it? If there is another way I want to use it.
That is entirely normal. One job of a control designer is to intercept the behavior of certain properties and methods that interfere with the use of the control in the design view. The Enabled property is one of them, if that would work at design-time as well then you could never select the control again. The designer can't let that happen of course, it always forces Enabled = true at design time and intercepts assignments to the property. As you found out. Overriding it can work either, it is not a virtual property, but wouldn't give you what you want anyway. The Visible property is another one that's intercepted like that, you can imagine how that goes wrong :)
You would have to create your own designer to do something about it. This in general tends to be a bazooka to kill a mosquito, especially in this case since you still can't do anything with Enabled. And worse, this behavior is implemented by the ControlDesigner class, the kind of class you need as a base class to get a designer going. I seriously doubt it is practical.
Doing nothing at all to fix this is entirely reasonable, given that none of the other controls in the toolbox change their appearance either when you change their Enabled property in the designer.
Related
Let's say I create a custom control which embed a trackbar. I also create an orientation property for my custom control.
When I drop the custom control on a form by default it will be horizontal. Then I set it to vertical, the trackbar should refresh to be vertical at design time.
How to do so ?
I think you should call Refresh() after changing the value:
public OrientationProperty Direction
{
get
{
return _direction;
}
set
{
_direction = value;
if (DesignMode)
{
Parent.Refresh(); // Refreshes the client area of the parent control
}
}
}
private OrientationProperty _direction;
Here's my solution to this issue:
1. Whenever you set something property, call Invalidate() in the setter.
2. After correspondent properties and refreshing method (for eg. overridden OnPaint) are implemented, rebuild!!! then you'll see the modifications taken effect in design time
3. During design, always check whether compilation errors are present, as this might stop VS performing all his tasks.
With this, when I put my control on a form, and adjust its own properties, refreshing happens immediately as expected.
PS.: old post, but at least verified the behavior in VS2015 too :)
How can I set the backgroundcolor and fontcolor to be "normal" on a disabled (i.e. Enabled = false) RichTextBox?
Thanks
Windows User Interface guidelines demand that a control that is disabled appears disabled. With the obvious benefit that the user can tell that it won't make sense to keep banging the mouse on the control, trying to set the focus to it. Like all controls in the toolbox, RichTextBox implements this guideline as well. Overriding its painting behavior is not practical. Consider the ReadOnly property.
I would create a new control that inherits from RichTextBox. You could the override the BackColor property to always return something like white for example. Something similar could be done with the font color. Off the top of my head I think you could do something such as:
class CustomRichTextBox : System.Windows.Forms.RichTextBox {
public override System.Drawing.Color BackColor {
get { return System.Drawing.Color.White; }
set { base.BackColor = System.Drawing.Color.White; }
}
}
Though that may not work because you would probably have to override the OnPaint method to get around default greyed out behavior.
Another option would be to simply use the readonly property instead. ReadOnly is almost the same as enabled = false, except that you can actually still click in the text box (you just can't edit it). When it is readonly, you still have control over the normal color properties without having to override anything.
If you wanted to be even more creative, you could add a delegate to the Enter event of the RichTextBox that set the focus to some other control to prevent the user from even clicking in the box (which enabled doesn't let you do)
Emulate the property of being disabled. Implement a property that when set to false the control won't get focus or all key strokes are ignored.
Pretty bizarre in my opinion but the programmer wants what the programmer wants! ;-]
I apologise if the title was confusing, it took me nearly 5 minutes to finally think of a title for this one...
Okay, you know how in Visual Studio Express when you add a TabControl to the Form, and you can click on the right-arrow on the top right of the TabControl and it will add a new TabPage, or remove one?
Well, I'm creating a User Control where I need people to be able to switch between Panels (my user control is made up of several Panels). I know this is possible as I've used a Ribbon Control in the past and you could add new buttons etc in the Designer View.
Can somebody please provide any suggestions/advice on how I might go about acheiving this?
Thank you
If I understand your question correctly, you're talking about smart tags.
The process is a little bit involved, so I'm not going to try to post a complete sample. Instead, I'll refer you to this tutorial on the subject. To make a long story short, you have to create a custom designer, and register one or more custom actions. You can use this to create a combo box listing the available panels and switch between them when the selected item is changed.
(Note - the term "smart tags" has two distinct meanings in Visual Studio - I'm specifically talking about the visual designer smart tags, not smart tags in the code editor).
When you make a control that is inherited from Control, you have to make use of a couple of properties such as IsDesignMode, you can then construct event handlers especially for within Design Mode:
if (IsDesignMode){
// Handle the interactivity in Design mode, such as changing a property on the
// Properties toolbox
}
Suppose the control has an event such as MouseClick, you can do this:
private void control_MouseClick(object sender, MouseEventArgs e){
if (IsDesignMode){
// Do something here depending on the Click event within the Designer
}else{
// This is at run-time...
}
}
Another I can think of is 'ShouldSerialize' followed by a publicly accessible property in order to persist the property to the designer-generated code, suppose for example a Control has a boolean property Foo
public bool Foo{
get{ return this._foo; }
set{ if (this._foo != value){
this._foo = value;
}
}
}
public bool ShouldSerializeFoo(){
return true; // The property will be persisted in the designer-generated code
// Check in Form.Designer.cs...
}
If ShouldSerializeFoo returned false, no property is persisted, its the opposite when true, it will be buried within the Form.Designer.cs code...
Hope this helps,
Best regards,
Tom.
I'd like to create a derived control from System.Windows.Forms.ComboBox that is bound to a list of objects that I retrieve from the database. Idea is other developers can just drop this control on their form without having to worry about the datasource, binding, unless they want to.
I have tried to extend combobox and then set the DataSource, DisplayMember, and ValueMember in the constructor.
public class CustomComboBox : ComboBox
{
public CustomComboBox()
{
this.DataSource = MyDAL.GetItems(); // Returns List<MyItem>
this.DisplayMember = "Name";
this.ValueMember = "ItemID";
}
}
Works when I run, but throws a lot of errors in Visual Studio's once it's added to any form. The error I get is:
"Code generation for property 'Items' failed. Error was: 'Object reference not set to an instance of an object"
What's the correct way to accomplish this (C#, Winforms, .NET 2.0+)?
The problem is that the designer actually does some compilation and execution in a slightly different context than normally running the program does.
In the constructor, you can wrap your code in:
if (!DesignMode)
{
//Do this stuff
}
That will tell the designer to not run any of your initialization code while it is being designed.
DesignMode property doesn't work in a constructor. From googling for a while, found this LicenseManager thing.
if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
{
// Do your database/IO/remote call
}
However LicenseManager only works in constructors. For eventhandlers use DesignMode.
Source: http://dotnetfacts.blogspot.com/2009/01/identifying-run-time-and-design-mode.html
Another reference: http://weblogs.asp.net/fmarguerie/archive/2005/03/23/395658.aspx
My usual comment here - DesignMode is not reliable in any situation other than if the control is placed directly on a design surface - i.e. if the control is placed on another control, DesignMode is not true even if you are in design mode. I have found NO reliable way to tell if you are in design mode - especially with inherited controls. Even variants using Site are not reliable if the control is inherited from a non-visual control (e.g. Common Dialog).
See http://keyofdflat.livejournal.com/5407.html (make sure to read the last comment).
I have an owner-drawn UserControl where I've implemented double-buffering. In order to get double-buffering to work without flicker, I have to override the OnPaintBackground event like so:
protected override void OnPaintBackground(PaintEventArgs e)
{
// don't even have to do anything else
}
This works great at runtime. The problem is that when I have an instance of the control on a form at design time, it becomes a black hole that shows trails of whatever windows are dragged over it (because the override of the OnPaintBackground event also governs design-time appearance). It's just a cosmetic problem, but it's visually jarring and it always leads new developers on the project to assume something has gone horribly wrong.
Is there any way to have an overridden method like this not be overridden at design time, or is there another solution?
Steven Lowe's solution unfortunately cover all scenarios, espcially when user controls come into the picture.
The this.DesignMode flag is very deceptive. Its only scope is to check if the direct parent is within the designer.
For instance, if you have a Form A, and a UserControl B, in the designer:
A.DesignMode is true when viewed in designer
B.DesignMode is false when viewing A, but true when looking directly at B in the designer.
The solution to this is a special flag to check (sorry for the ugly C++ code):
if(this->DesignMode ||
LicenseManager::UsageMode == LicenseUsageMode::Designtime)
return;
This variable will always show the proper design boolean.
if (this.DesignMode)
{
return; //or call base.OnPaintBackground()
}
The solution of greggorob64 in C#:
if (DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
return;
}