Windows Develop Bookmark and Share   
 index > Windows Forms Designer > How to prevent Designer from executing code in a UserControl's Load event.
 

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
---------------------------

JocularJoe  Thursday, April 26, 2007 7:54 PM

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");
}
}
decyclone  Friday, April 27, 2007 6:56 AM

> if (Site != null && Site.DesignMode) return;

This is exactly equivalent to the code in the example from the original post ("if (!this.DesignMode)..."

It worksin the simple case of aForm containing a UserControl, but does not work in the case of a nested UserControl described above (Form1 contains UserControlA contains UserControlB).

JocularJoe  Friday, April 27, 2007 4:41 PM

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 anywaysomeone pointed out that it may fail under Citrix Metaframe if the user does not haveenough permission to get process information.


JocularJoe  Monday, April 30, 2007 5:25 PM

I ran into this problem too, and ended up with the following hack, which I found less distasteful than the devenv check:

Code Snippet
public 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.

fastcat  Thursday, May 17, 2007 6:52 PM
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.)
Malacki  Friday, May 18, 2007 1:39 AM

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 Snippet

If Not Diagnostics.Debugger.IsAttached Then

''Run Time Mode

End If

''Instead of your code

If Not Me.DesignMode Then

''Run time mode

End If

and problem solved , So you can check this & if not solved we can search for more intelligent solution

Pr.Wael  Sunday, May 27, 2007 6:37 AM

> i solved it with following statment

> If Not Diagnostics.Debugger.IsAttached Then

> ''Run Time Mode

> End If

I'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?

JocularJoe  Monday, May 28, 2007 8:06 PM

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 Snippet

Try

Return (System.Diagnostics.Process.GetCurrentProcess().ProcessName = "devenv")

Catch

Return False

End Try

Just my 2 cents.

Thanks,

Andy

Andeezle  Thursday, June 07, 2007 10:55 PM

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 T

India

SachinT  Tuesday, September 11, 2007 5:44 PM
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
edwardsayer  Tuesday, September 15, 2009 3:15 AM

You can use google to search for other answers

Custom Search

More Threads

• UserControl and properties problem
• Adorner and Glyph Help with Dragging
• Bug - Getting the SelectedItem in ListBox
• (URGENT)
• Global Parameters needed ...
• Master/Detail forms
• { URGENT } - DesignSurface style of moving/resizing user controls at runtime
• How to hide a property at run time?
• How can I modify the look of a form?
• Failed to create component 'AxHost'