Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Design Time / April 2007

Tip: Looking for answers? Try searching our database.

How to skip execution during Design Time?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Dave Leach - 23 Mar 2007 19:02 GMT
I am writing a Windows Forms application using .NET 1.1, VS 2003 and C#.

There is a section of code in one of my form's constructors that needs to be
skipped over if the constructor is being called at design time.

Is there a way to conditionally execute this code only at runtime and not at
design time?

Thanks,
Dave
Signature

Dave Leach
Agilent Technologies, Inc.

Sergey M - 24 Mar 2007 04:11 GMT
> There is a section of code in one of my form's constructors that
> needs to be
> skipped over if the constructor is being called at design time.

You can check form's Site.DesignMode property, which is set to true at
design time. The caveat there is that constructor is too early to
check for that as component is not yet sited at that point. You could
try overriding OnLoad() to see if that helps.
Signature

Sergey Mishkovskiy
http://www.usysware.com/dpack/ - DPack - free VS add-ons
http://www.usysware.com/blog/

Linda Liu [MSFT] - 26 Mar 2007 05:46 GMT
Hi Dave,

Firstly, when we open a form in the designer, the code in the form's
constructor won't be called.

You have mentioned that you have a section of code in one of your form's
constructors that needs to be skipped over if the constructor is being
called at design time. It seems that the section of code must be in a base
form's constructor, and what you open in the form designer is an inherited
form.

It's no use to make use of the form's DesignMode property in the
constructor to determine whether it is at design time or run time, because
the Site property of the form has not been assigned when the form is being
constructed. The DesignMode property of the form always returns false when
we get its value in the constructor.

When the form's Load event handler is called, the form has already finished
the construction and the DesignMode property has a valid value. So the
solution is to move the section of code that you need to prevent from being
executed at design time to the form's Load event handler, and add a
condition of "! this.DesignMode" on the section of code.

Alternatively, you could implement the ISupportInitialize interface for the
base form and move the section of code to either of the ISupportInitialize
members -- BeginInit or EndInit method (of course, you still need to add "!
this.DesignMode" condition on the section of code).

When the base form implements the ISupportInitialize interface and we open
the inherited form in the designer, the code to call the
ISupportInitialize.BeginInit and ISupportInitilize.EndInit methods are
serialized in the InitializeComponent method of the inherited form. When
the ISupportInitialize.BeginInit or ISupportInitialize.EndInit method is
executed, the base form has already finished the construction, thus the
DesignMode property returns a valid value at this time.

Hope this helps.
If you have anything unclear, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
Dave Leach - 28 Mar 2007 01:59 GMT
Linda,

I have experimented with the ISupportInitialize interface, but without
success.  I have copied some very simplified code below to demonstrate how I
have tried to use this interface.  Note that I am applying the interface to a
derived control instead of the derived form as the original message stated.  
This seemed like the more correct location for my application.

When I try to display the "DerivedForm" with the Forms Designer, the code
that causes the assert is still being reached, even though that code is
called from the EndInit() method and includes a test for DesignMode.

Please look at the code below and let me know if I am missing something.

Thanks,
Dave

===============Code Starts Here=================
  public class MyPanelBase : System.Windows.Forms.UserControl,
ISupportInitialize
  {
     public MyPanelBase()
     {
        InitializeComponent();
     }

     protected virtual void FinishConstruction()
     {
        DoSomethingThatAssertsAtDesignTime();
     }

     // Virtual method overridden by derived class.
     protected virtual void DoSomethingThatAssertsAtDesignTime()
     {}

     public void BeginInit()
     {}

     public void EndInit()
     {
        if ( !this.DesignMode )
        {
           DoSomethingThatAssertsAtDesignTime();
        }
     }
  }

  public class DerivedPanel : MyPanelBase
  {
     public DerivedPanel() : base()
     {
        InitializeComponent();
     }

     protected override void DoSomethingThatAssertsAtDesignTime()
     {
        DoSomethingAtRuntime(); // Causes VS2003 Assert at DesignTime.
     }

     private void InitializeComponent()
     {
        ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
        this.SuspendLayout();

        // Controls go here...

        ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
        this.ResumeLayout(false);
     }
  }

  public class DerivedForm : ChildFormBase
  {
     private DerivedPanel myDerivedPanel;

     public DerivedForm() : base()
     {
        InitializeComponent();
     }

     private void InitializeComponent()
     {
        this.myDerivedPanel = new DerivedPanel();
       
((System.ComponentModel.ISupportInitialize)(this.myDerivedPanel)).BeginInit();
        this.SuspendLayout();
        //
        // myDerivedPanel
        //
        this.myDerivedPanel.Location = new System.Drawing.Point(0, 50);
        this.myDerivedPanel.Name = "myDerivedPanel";
        this.myDerivedPanel.Size = new System.Drawing.Size(410, 140);
        this.myDerivedPanel.TabIndex = 0;
        //
        // DerivedForm
        //
        this.AutoScaleBaseSize = new System.Drawing.Size(7, 17);
        this.ClientSize = new System.Drawing.Size(432, 643);
        this.Controls.Add(this.myDerivedPanel);
        this.Icon =
((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
        this.Name = "DerivedForm";
        this.Text = "My Form";
       
((System.ComponentModel.ISupportInitialize)(this.myDerivedPanel)).EndInit();
        this.ResumeLayout(false);
     }
  }
===============Code Ends Here==================
Signature

Dave Leach
Agilent Technologies, Inc.

> Hi Dave,
>
[quoted text clipped - 58 lines]
>  
> This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu [MSFT] - 28 Mar 2007 04:46 GMT
Hi Dave,

Thank you for your feedback and sample code.

I performed a test based on your sample code and did reproduce the problem
on my side. To make things clear, I modify the code in the EndInit method
within the MyPanelBase class as follows:

public class MyPanelBase : System.Windows.Forms.UserControl,
ISupportInitialize
{
      .....
      public void EndInit()
     {
        // if ( !this.DesignMode )
        // {
        //    DoSomethingThatAssertsAtDesignTime();
        // }
            MessageBox.Show("in EndInit: MyPanelBase.DesignMode=" +
this.DesignMode.ToString());
     }
}

Buid the project and re-open the form that contains the DerivedPanel
control. The result is that the message box pops up twice--for the first
time, it shows "in EndInit: MyPanelBase.DesignMode=false" and for the
second time, "in EndInit: MyPanelBase.DesignMode=true".

The reason why the EndInit method is called twice is that the statement
"((System.ComponentModel.ISupportInitialize)(this)).EndInit();" is
serialized in the InitializeComponent method within the DerivedPanel class
as well as in the InitializeComponent method within the form that contains
the DerivedPanel control.

When we open the form that contains the DerivedPanel, an instance of the
DerivedPanel class is created, so the constructor of the DerivedPanel is
called, which in turn calls the InitializeComponent method. Note that the
instance of the DerivedPanel has not finished the construction, so the
value of its DesignMode property is FALSE at this time.

When the InitializeComponent method of the form is called, the instance of
the DerivedPanel has already finished the construction, so the DesignMode
property of the DerivedPanel returns true.

As for your practice, I suggest that you move the section of code to the
MyPanelBase's Load event handler. This event handler will be called only
once and after the instance of the DerivedPanel has finished the
construction.

Hope I make some clarification.

If you have anything unclear, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support
Dave Leach - 28 Mar 2007 17:06 GMT
Linda,

The suggestion to move a section of code to the Load event handler is not an
acceptable solution.  That section of code is related to our system
initialization.

The initialization (at runtime) needs to execute at construction time for
reasons related to the required system performance.  We do not want the
initialization to be deferred to the form's load time.

Is there another solution available other than ISupportInitialize (which
appears to not be a solution)?  Are there any other interfaces or attributes
that could solve this problem?

Regards,
Dave
Signature

Dave Leach
Agilent Technologies, Inc.

> Hi Dave,
>
[quoted text clipped - 52 lines]
> Linda Liu
> Microsoft Online Community Support
Linda Liu [MSFT] - 30 Mar 2007 09:56 GMT
Hi Dave,

Thank you for your reply.

What I'd like to say is that it's a recommended way to place the section of
code to the EndInit method to prevent it from being executed at design
time.

This workaround works great in the case that you have a UserControl which
has a section of code that needs to be executed at construction time as
well as at run time.

However, this workaround doesn't work well for a more complex scenario,
e.g. you derive a new control from the UserControl that implements the
ISupportInitialize interface and then drag&drop the derived control onto a
form in the designer.

As I have pointed out in my last reply, the key point of the problem is
that the call to the EndInit method is serialized to the
InitializeComponent method of the derived control, which I think may not
necessary because the call to the EndInit method will be serialized to the
InitializeComponent method of the form when we drag&drop the derived
control onto it.

I'm sorry that I don't think there is a interface/attribute other than the
ISupportInitialize interface that could solve this problem.

I suggest that you comment out the call to the EndInit method in the
InitializeComponent method within the derived UserControl, and build the
project , and then drag&drop the derived control onto a form in the
designer.

Note that if you re-configure the derived UserControl in the designer, the
code in the InitializeComponent will be refreshed by the designer
automatically and the call the EndInit method will be serialized again. You
should comment this code out and then build the project again.

Although it is not very elegant, it does work for your complex scenario.

If you have any concern, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support
Dave Leach - 10 Apr 2007 18:38 GMT
Linda,

Sorry I have not replied before now.  I was on vacation last week.  Before I
left I came up with a solution that works, but I felt was a hack and
commented it as such.  Now I guess I'll remove the "hack" comment.

The solution was to add a static boolean that will only be set to true
within our initialization code at run time.  During design time this boolean
is false and will prevent the code that generates the exception from being
executed.

As for commenting out the call to the EndInit method:  I will not take this
approach as that requires future developers to somehow know to repeat that
process any time they make changes to the derived UserControl using the forms
designer.

You should consider this issue closed.  I will clean-up and add appropriate
comments to the static boolean solution I have implemented.

Regards,
Dave
Signature

Dave Leach
Agilent Technologies, Inc.

> Hi Dave,
>
[quoted text clipped - 40 lines]
> Linda Liu
> Microsoft Online Community Support
Frank Hileman - 30 Mar 2007 13:25 GMT
Hi Dave,

We have some experience in this area. The only safe assumption is to assume
it is design-time during construction, until told otherwise. In run-time
code call a method on a top-level object that is propagated to lower level
objects (via collection iteration), informing all sub-objects it is not
design-time, but run-time. You could create an interface containing this
method.

That technique works even if your component is deep in a hierarchy. For
example, placing a UserControl in another UserControl, and then placing it
on a Form. In that case the lowest-level UserControl will never be marked
DesignMode == true while editing the Form, even after construction.

A second approach is to use a static property or field available globally,
signifying run-time mode. By default, it signals design-time mode, and is
only set to run-time mode truly at run-time. In this case, as long as you
initialize the field/property before any objects are constructed, you can
refer to that mode even during construction, and it is accurate.

Regards,
Frank Hileman

check out VG.net: http://www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio graphics editor

> Linda,
>
[quoted text clipped - 11 lines]
> attributes
> that could solve this problem?
Dave Leach - 10 Apr 2007 18:48 GMT
Frank,

Thanks for taking the time to post a reply.  I implemented a similar
solution to the one you have suggested, however at the time I considered it a
hack.  I was hoping that Microsoft had a solution for controlling execution
during design time.  Now I will be making my hack a permanent solution.

I am fortunate that our system design provides an ordered initialization
sequence that I can take advantage of and guarantee that a static flag can be
set before any of my forms or controls are constructed.

Thanks again,
Dave
Signature

Dave Leach
Agilent Technologies, Inc.

> Hi Dave,
>
[quoted text clipped - 38 lines]
> > attributes
> > that could solve this problem?

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.