.NET Windows Forms design time rules
You could also use this to check if the Visual Studio Designer is running the code:
public static bool DesignMode
{
get { return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"); }
}
Then in Form_Load:
if (!DesignMode)
{
// Run code that breaks in Visual Studio Designer (like trying to get a DB connection)
}
However, this is less elegant than using the LicensManager.UsageMode
, but it works (until Microsoft changes the name of the process Visual Studio runs under).
You can check the UsageMode of the LicenseManager, to check if the code is in design time or not.
System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime
Here is a quick example:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Test
{
public class ComponentClass : Component
{
public ComponentClass()
{
MessageBox.Show("Runtime!");
}
}
}
When this component gets add to your form in the designer, you will immediatly get a message box.
To prevent this you can add a simple if statement to check if the code is not in design time
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Test
{
public class ComponentClass : Component
{
public ComponentClass()
{
if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
{
MessageBox.Show("Runtime!");
}
}
}
}
After adding the if statement, the messagebox no longer appears when the component is added to the form via the designer.
Well, since this has been resurrected anyway, here's the function I use to determine whether I'm in design mode:
public static bool IsAnyInDesignMode(Control control){
while(control != null){
if(control.Site != null && control.Site.DesignMode)
return true;
control = control.Parent;
}
return false;
}
This handles the case where the control is a child created by another control. The DesignMode
property is only set for controls created by the designer itself.
The constructor of a control or form does not get executed when editing that class in the designer (nor does OnLoad get called). I've occasionally used this to set one value in the designer (eg. making its child controls all Visible in the designer) but override some of them to a different default value in the constructor (eg. hiding certain child controls which will only show in certain circumstances, such as an indicator on a status bar).
However, the constructor does get executed if the control is placed as a child on another control or form in the designer. OnLoad gets executed as well. This may be how your logging code was getting accidentally triggered in the designer.
For detecting design vs runtime, an answer to another question has screenshots of some emperical tests showing the values returned by some common approaches. It appears that a child control of a child control (two levels down) of the form or control being edited in the designer sees its own DesignMode == false, so the normal property check will fail to protect code (eg. in the OnLoad method) for controls nested within a control added in the designer. If you were checking DesignMode as one would expect, it could be the nesting which caused it to get around that check. It also always sees DesignMode == false within the constructor.
Also, note that the LicenseManager.UsageMode check only sees DesignTime within the constructor; when OnLoad is called it is within a RunTime LicenseContext. The most complete solution seems to be to check LicenseManager.UsageMode in the constructor of the control or form (or component) and save the setting to a member variable or property which you can check later to avoid running code that should never run in the designer even when nested. There's also another approach in another answer to that other question which accounts for nesting but only works outside the constructor.