How to prevent Designer from executing code in a UserControl's Load event.
Consider a WinForms application with a form Form1 and a UserControl UserControlA.
If you drag and drop UserControlA on to Form1 in the VS2005 Designer, then the Designer will execute UserControlA's Load event handler(s) each time Form1 is opened in the Designer.
This can be highly undesirable, for example a Load event handler may contain application code to connect to a database etc that should not be executed at design time.
In the above scenario, a workaround is to test the DesignMode property in the Load event handler, and skip unwanted processing if DesignMode is true.
However, this workaround does not work for nested UserControls.
Consider a project with a form Form1, and two UserControls UserControlA and UserControlB. Drag and drop UserControlB on to UserControlA, and UserControlA on to Form1. Build then open Form1 in the VS designer.
In this case, UserControlB's Load event is executed by the designer, and the DesignMode property is set to false.
For example, if UserControlB's Load event handler contains the following code, the MessageBox below is displayed:
private void UserControlB_Load(object sender, EventArgs e)
{
if (!this.DesignMode)
{
MessageBox.Show("In UserControlB Load event\n" + Environment.StackTrace);
}
}
Is there any way to prevent code in the Load event handler from being executed by the designer in this general case where UserControls are nested?
Thanks,
Joe
MessageBox displayed by the above code when Form1 is opened in the VS designer:
---------------------------
---------------------------
In UserControlB Load event
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)at System.Environment.get_StackTrace()
at TestUserControlDesigner.UserControlB.UserControlB_Load(Object sender, EventArgs e) in C:\TestUserControlDesigner\TestUserControlDesigner\UserControlB.cs:line 22
at System.Windows.Forms.UserControl.OnLoad(EventArgs e)
at System.Windows.Forms.UserControl.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.ControlCollection.Add(Control value)
at System.Windows.Forms.Form.ControlCollection.Add(Control value)
at System.Windows.Forms.Design.ControlDesigner.DesignerControlCollection.Add(Control c)
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)
at System.ComponentModel.Design.Serialization.CodeDomSerializer.DeserializeStatementToInstance(IDesignerSerializationManager manager, CodeStatement statement)
at System.ComponentModel.Design.Serialization.CodeDomSerializer.Deserialize(IDesignerSerializationManager manager, Object codeObject)
at System.Windows.Forms.Design.ControlCodeDomSerializer.Deserialize(IDesignerSerializationManager manager, Object codeObject)
at System.ComponentModel.Design.Serialization.TypeCodeDomSerializer.DeserializeName(IDesignerSerializationManager manager, String name, CodeStatementCollection statements)
at System.ComponentModel.Design.Serialization.TypeCodeDomSerializer.Deserialize(IDesignerSerializationManager manager, CodeTypeDeclaration declaration)
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.DeferredLoadHandler.Microsoft.VisualStudio.TextManager.Interop.IVsTextBufferDataEvents.OnLoadCompleted(Int32 fReload)
---------------------------
OK
---------------------------
All Replies
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void LoadUserControl_Load(object sender, EventArgs e)
{
if (Site != null && Site.DesignMode) return;
MessageBox.Show("Test");
}
}> if (Site != null && Site.DesignMode) return;
This is exactly equivalent to the code in the example from the original post ("if (!this.DesignMode)..."
It works in the simple case of a Form containing a UserControl, but does not work in the case of a nested UserControl described above (Form1 contains UserControlA contains UserControlB).
Having GTFW as I should have done before first posting, I see this is a known bug:
http://support.microsoft.com/kb/839202
No suggestion of a fix or workaround though.
Others have suggested testing "if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)" but this always returns false even when in design mode - perhaps it's a solution that works only in VS.NET 2003?
Finally there are suggestions to test "return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");" but this is too horrible a hack to contemplate, and anyway someone pointed out that it may fail under Citrix Metaframe if the user does not have enough permission to get process information.
I ran into this problem too, and ended up with the following hack, which I found less distasteful than the devenv check:
Code Snippetpublic static bool HasDesigner(Control control)
{
if (control == null)
return false;
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
return true;
Control p = control.Parent;
while (p != null)
{
// System.Windows.Forms.Design.DesignerFrame ... an internal type to System.Design
if (p.GetType().FullName.Contains(".DesignerFrame"))
return true;
p = p.Parent;
}
return false;
}The reason I check the type name string instead of comparing with a typeof() expression is that the System.Windows.Forms.Design.DesignerFrame is in the System.Design assembly, which is not normally referenced by applications.
- Do you have a particular UserControl or one used as a base class to which you can attach a custom designer? If so, maybe you could override PreFilterEvents in a custom designer and remove the Load event? (can't test this at the moment... not sure if you'd catch it in time or if it would really work.)
hi . i faced your problem in one of my custom controls i made before , but i solved it with your solution , then more complicated situations i faced your second problem , but i solved it with following statment
Code SnippetIf
Not Diagnostics.Debugger.IsAttached Then ''Run Time Mode End If''Instead of your code
If Not Me.DesignMode Then ''Run time mode End Ifand problem solved , So you can check this & if not solved we can search for more intelligent solution
> i solved it with following statment
> If Not Diagnostics.Debugger.IsAttached Then
> ''Run Time Mode > End IfI'm not sure what you're suggesting here - what does the debugger being attached have to do with testing for design mode?
What I was really hoping is that someone from Microsoft's Windows Forms team would chime in and explain what is going on. Is this what it appears to be, a fundamental flaw in the VS designer? If so, how come it's still not fixed in V2.0 of the Framework!
Or is it intentionally designed this way, and if so, how are developers intended to write UserControls that behave properly at design time?
All of my UCs inherit from a base UC that I've created in a base class lib.
My base UC obviously inherits from System.Windows.Forms.UserControl.
In my base UC, I shadow the sub-class implementation, Component.DesignMode.
And replace it with this: (it seems to work pretty good for me.)
Code SnippetTry
Return (System.Diagnostics.Process.GetCurrentProcess().ProcessName = "devenv") Catch Return False End TryJust my 2 cents.
Thanks,
Andy
Did any one find solution to this problem
In my project i have only one windows form which contains nested control
Onr nested control contains some code on form_load event which retrives data from database
as a result parent form (the only form shows error in design mode) Runtime it works perfectly
Rgds,
Sachin TIndia
- Andy's solution is workable!
To simplify things a lot, just create a method with following code:
public static bool InDesignMode()
{
try
{
return System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv";
}
catch
{
return false;
}
}
And in your client code:
if (!GuiUtil.InDesignMode())
{
InitDataBinding();
}
Regards,
Edward


