Introduction
Sometimes, you need to know inside a user control if the application is in design mode or not. For example, if the control is getting data from a database or from a web service, the connection may not be established at design time.
A control contains a property called DesignMode, but examining just its value isn't enough. The DesignMode
should be evaluated for the control and for the whole parent hierarchy in order to know the status of the application.
Another thing is that the DesignMode
is a protected
property, so it cannot be examined from outside the control in a 'traditional' way.
So the motivation for this tip was to create a simple extension method which recursively examines the DesignMode
and can be used from outside the control.
The Extension Method
The extension method is quite simple:
namespace Controls {
public static class Extensions {
public static bool IsInDesignMode(this System.Windows.Forms.Control control) {
return ResolveDesignMode(control);
}
private static bool ResolveDesignMode(System.Windows.Forms.Control control) {
System.Reflection.PropertyInfo designModeProperty;
bool designMode;
designModeProperty = control.GetType().GetProperty(
"DesignMode",
System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic);
designMode = (bool)designModeProperty.GetValue(control, null);
if (control.Parent != null) {
designMode |= ResolveDesignMode(control.Parent);
}
return designMode;
}
}
}
So the extension method simply calls the private
ResolveDesignMode
method. This method travels recursively through all the parents of the control to resolve if any control is in design mode.
The method finds out the DesignMode
property value for the control at hand. Since the property is protected
by design, getting the value by simply querying the property isn't possible. This is why reflection is used to get the property and then the value of the property. In order to get the property, NonPublic
binding flag must be used.
The Test Control
The test control contains just a textbox
. When the control is created, the text of the textbox
is set to describe if the control or any of its parents is in design mode or not.
The code is simple:
namespace Controls {
public partial class TestControl : UserControl {
public TestControl() {
InitializeComponent();
}
private void TestControl_Load(object sender, EventArgs e) {
this.txtText.Text = this.IsInDesignMode()
? "Program is in design mode"
: "The program is running";
}
}
}
The code to inspect if the design mode is true is written to the Load
event. This is because when the control is created on a window, its parent is set later in the designer generated code. This is why the parents cannot be found inside the constructor.
The Test Project
The test project contains a single window and two instances of the test control. One is placed on the window and the other one inside few containers in order to test that the parents are resolved correctly.
When in design mode, the window looks like:
And at run-time:
Final Words
Hopefully, this extension method helps to resolve the status of an application from inside or if needed, also from outside a user control.
Note: Before opening the window in the test project, remember to compile the whole solution since the download doesn't contain any binaries.
History
- 26th August, 2012: Created