Somtimes, a control needs to appear differently at design time than it does at runtime. This different appearance is often to indicate something to the developer, which will be irrelevant to a runtime user.
The standard approach to achieving this goal is to add additional code in the OnPaint method:
public class MyControl : Control { public override void OnPaint(object sender, PaintEventArgs e) { //Normal painting here if (!DesignMode) { //Design time painting here //Draw a rectangle around the control } } }
This works fine, but it is not ideal. Here, we are mixing runtime and design time code. Also, take into account what might happen if another control descends from this class and overrides OnPaint:
public class MyOtherControl : MyControl { public override void OnPaint(object sender, PaintEventArgs e) { //Call base, which draws a rect around the control Base.OnPaint(sender, e); //Some code which will draw over the rectangle } }
What we really need is a way of drawing to the e.Graphics object after the OnPaint method has finished completely, and also only during design time.
The solution lies in the ControlDesigner class and the Designer attribute.
public class MyControlDesigner : System.Windows.Forms.Design.ControlDesigner { public override void OnPaintAdornments(PaintEventArgs e) { //Design time painting here //Draw a rectangle around the control } }
Then, we just associate MyControlDesigner with the MyControl class. Note how the OnPaint method no longer has any design time painting in it.
[System.ComponentModel.Designer(typeof(MyNameSpace.MyControlDesigner))] public class MyControl : Control { public override void OnPaint(object sender, PaintEventArgs e) { //Normal painting here } }