DesignMode in WPF
One of the most common task of the custom controls' developers, is to determine whether their control is being used in run-time or it's being used in design time. For instance, If we provide a MyLabel control, we might want to display it's outlines on design-time, so that the designer who's using our control will be able to resize it, move it or rotate it.
This functionality is of course otiose when the end user is running our application in runtime (though there are cases we would like to enable those features, mostly it'll be used only in design-time).
The control designers (aka custom designers) area was extremely moderated in WPF. My troubles began when I've tried to create my first custom WPF control. My new control was supposed to be manipulated using the Expression Blend by UI experts, so I had to provide a really simple designer. I've wanted to enhance its automatic behavior by adding automatic docking inside panels and grids, and influence other properties I could predict its values.
My first step was of course - determine whether the control is being invoked through a designer or in runtime.
A brief history:
At the beginning, every UserControl implemented a property called DesignMode, which returned true value in case the control was initialized in a designer. This implementation was imperfect due to some problems:
- It was impossible to get a valid result inside the constructor of the control. The DesignMode property could return its value only after the InitializeComponents was de-serialized by the designer.
- Nested control had problems returning their DesignMode.
- At that time, there was only one supported IDE for control designing, Visual Studio 2003/2005. WPF, for the first time, was supported by new tools (e.g. Visual Studio 2005 CTP extensions, Visual Studio 2008 aka Orcas, Expression Blend etc.). So the past implementation could not provide information about the designer, but only could give some basic orientation whether the control is being designed or not.
This is how it was done in WinForms:
class CustomButton : Button
{
public CustomButton()
{
if (this.DeisgnMode)
{
this.Text= "In Design Mode";
}
else
{
this.Text= "Runtime";
}
}
}
On one hand, in one of its early CTPs, WPF could provide its accurate design mode using a global parameter which could be read as a DependencyProperty through the AppDomain. But on the other hand, It was filthy. (BTW, in WinForms the parameter could also be accessed globally using the LicenseManager..).
The code snippet which was published those days was something like this:
bool IsDesignMode
{
get
{
DependencyProperty isDesignModeProperty =
(DependencyProperty)AppDomain.CurrentDomain
.GetData("IsDesignModeProperty");
return isDesignModeProperty == null ? false :
true.Equals(isDesignModeProperty.GetValue(this));
}
}
As it seems, due to a talkback of some reader of UrbanPotato's blog (A Cider internal..), this was changed and a new way was introduced. A new class called DesignerProperties was injected to the ComponentModel. The DesignerProperties class implements the method GetIsInDesignMode, which returns a boolean indicating whether the application is running in design mode. Also, using this new class we can get further details about the designer.
This is how it looks today (VS2008 Beta 1 & VS2005 WPF extensions):
public class CustomButton : Button
{
public CustomButton()
{
if (System.ComponentModel.DesignerProperties
.GetIsInDesignMode(this))
{
Content = "In Design Mode";
}
else
{
Content = "Runtime";
}
}
}
blog comments powered by