DesignMode with nested Controls
Revisiting this question, I have now 'discovered' 5 different ways of doing this, which are as follows:
System.ComponentModel.DesignMode property
System.ComponentModel.LicenseManager.UsageMode property
private string ServiceString()
{
if (GetService(typeof(System.ComponentModel.Design.IDesignerHost)) != null)
return "Present";
else
return "Not present";
}
public bool IsDesignerHosted
{
get
{
Control ctrl = this;
while(ctrl != null)
{
if((ctrl.Site != null) && ctrl.Site.DesignMode)
return true;
ctrl = ctrl.Parent;
}
return false;
}
}
public static bool IsInDesignMode()
{
return System.Reflection.Assembly.GetExecutingAssembly()
.Location.Contains("VisualStudio"))
}
To try and get a hang on the three solutions proposed, I created a little test solution - with three projects:
- TestApp (winforms application),
- SubControl (dll)
- SubSubControl (dll)
I then embedded the SubSubControl in the SubControl, then one of each in the TestApp.Form.
This screenshot shows the result when running.
This screenshot shows the result with the form open in Visual Studio:
Conclusion: It would appear that without reflection the only one that is reliable within the constructor is LicenseUsage, and the only one which is reliable outside the constructor is 'IsDesignedHosted' (by BlueRaja below)
PS: See ToolmakerSteve's comment below (which I haven't tested): "Note that IsDesignerHosted answer has been updated to include LicenseUsage..., so now the test can simply be if (IsDesignerHosted). An alternative approach is test LicenseManager in constructor and cache the result."
Why don't you check LicenseManager.UsageMode. This property can have the values LicenseUsageMode.Runtime or LicenseUsageMode.Designtime.
Is you want code to only run in runtime, use the following code:
if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
{
bla bla bla...
}
This is the method I use inside forms:
/// <summary>
/// Gets a value indicating whether this instance is in design mode.
/// </summary>
/// <value>
/// <c>true</c> if this instance is in design mode; otherwise, <c>false</c>.
/// </value>
protected bool IsDesignMode
{
get { return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime; }
}
This way, the result will be correct, even if either of DesignMode or LicenseManager properties fail.
From this page:
([Edit 2013] Edited to work in constructors, using the method provided by @hopla)
/// <summary>
/// The DesignMode property does not correctly tell you if
/// you are in design mode. IsDesignerHosted is a corrected
/// version of that property.
/// (see https://connect.microsoft.com/VisualStudio/feedback/details/553305
/// and http://stackoverflow.com/a/2693338/238419 )
/// </summary>
public bool IsDesignerHosted
{
get
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
return true;
Control ctrl = this;
while (ctrl != null)
{
if ((ctrl.Site != null) && ctrl.Site.DesignMode)
return true;
ctrl = ctrl.Parent;
}
return false;
}
}
I've submitted a bug-report with Microsoft; I doubt it will go anywhere, but vote it up anyways, as this is obviously a bug (whether or not it's "by design").