views:

322

answers:

6

With several forms of mine, I occasionally run into the following issue: I edit the form using the designer (Visual Studio 2008, Windows Forms, .NET 2.0, VB.NET) to add components, only to find out later that some minor adjustments were made (e.g. the form's size is suddenly changed by a few pixels), and controls get deleted. This happens silently — event-handling methods automatically have their Handles suffix removed, too, so they never get called, and there's no compiler error. I only notice much later or not at all, because I'm working on a different area in the form.

As an example, I have a form with a SplitContainer containing an Infragistics UltraListView to the left, and an UltraTabControl to the right. I added a new tab, and controls within, and they worked fine. I later on found out that the list view's scrollbar was suddenly invisible, due to its size being off, and at least one control was removed from a different tab that I hadn't been working on.

Is this a known issue with the WinForms Designer, or with Infragistics? I use version control, of course, so I can compare the changes and merge the deleted code back in, but it's a tedious process that shouldn't be necessary. Are there ways to avoid this? Is there a good reason for this to occur?

One clue is that the control that was removed may have code (such as a Load event handler) that expects to be run in run time, not design time, and may be throwing an exception. Could this cause Visual Studio to remove the control?

A: 

I've seen this happen with VB6 and early .NET when the OS was having problems. We had to do a Reboot and repair.

Dave
I've seen this across multiple VMs, i.e. distinct installations of VS.
Sören Kuklau
@Dave- This is an all too normal VS.Net/WinForms issue.
Jim Leonardo
+3  A: 

This is not an answer to your question, but remember that you should use "DesignMode" in loads This avoids weird unexpected behaviors during design time.

    private void EureFormAbm_Load(object sender, System.EventArgs e)
    {

        if (!DesignMode)
        {
            // your code
        } /* if */
    }

or

    private void EureFormAbm_Load(object sender, System.EventArgs e)
    {
        if (DesignMode)
              return;
             // your code


    }
Daniel Dolz
+1 This is part of what needs to be done to keep your sanity when working with winforms.
Jim Leonardo
Thanks. This seems the most likely cause to me.
Sören Kuklau
A: 

No real answer for you, but some more pointers I've found helpful..

A) See @Daniel Dolz's answer. I wholeheartedly recommend you ALWAYS do what he's recommendation except when you avoid putting non UI code (or any code) in Form_Load altogether. This actually solves a lot of problems, but especially those exceptions popping up in designers and slow designer performance.

B) As much as humanly possible:

NEVER EDIT THE DESIGNER.CS IN WINFORMS.

Ok, sometimes you have to, but it's not someplace to do regular development. 3rd party controls will have bugs that require you to do so, but it should be an exceedingly rare day when you're making a direct change in the designer file. One way to help manage this is that if you don't want the designer automatically adjusting something, copy it over to your regular .cs file. That doesn't cover everything, but keep it in mind.

C) Also, do you know you can Lock the layout via the IDE to prevent stray mouse clicks from goofing everything up on you? This will preempt some of these "automatic updates" you're running into.

Parting Shot I worked on a large Winforms project for 2yrs+ immediately prior to my current project and all I can say is until we put an end to ppl editing the designers except for very minor edits and required them to put in the DesignMode checks, we had nothing but problems. Coming off of web projects, we have a hard time with this idea b/c we're so used to editing markup, but the designer.cs isn't the same as markup.

Jim Leonardo
+1  A: 

If you can reproduce the problem, then you can determine whether or not the cause is an exception. Start a second instance of Visual Studio and use "Tools->Attach to Process" to attach to the first one. Then proceed to reproduce the problem, and the code should break when the unhandled exception is thrown. Information about other exceptions (possibly handled) will be visible in the Output window.

John Saunders
+1  A: 

I voted up John Saunders answer because that's how I'd also recommend tracking down any exceptions the designer may be encountering.

Daniels answer is also good advice but I've found the DesignMode property sometimes produces an unexpected result. Below is a property I have on my base control class (most controls I created inherit from this), the comments should indicate the 'reason' for what looks like hacky code but essentially this is much more reliable than DesignMode on its own.

    /// <summary>
    /// Indicates if the current view is being utilized in the VS.NET IDE or not.
    /// </summary>
    /// <remarks>The DesignMode property for a UserControl object will show that it is in DesignMode 
    /// only if the immediate parent is viewed in the IDE; if it is a grand child of the object that is being viewed in the IDE, 
    /// then the DesignMode property will not be true.
    /// This is a workaround</remarks>
    public bool InDesignMode
    {
        get
        {
            // Site.Design mode sometimes produces a better result.
            if (DesignMode || Site != null && Site.DesignMode)
                return true;
            Control parent = Parent;
            while (parent != null)
            {
                if (parent.Site != null && parent.Site.DesignMode)
                    return true;
                parent = parent.Parent;
            }

            // Note: not 100% sure abuot this one, need to double check
            // if in design mode then entryAssembly will be null. This check is needed because DesignMode property is only true for the control 
            // that is actively being designed, so child controls will be false...we do check the Parent heirarchy in InDesignMode but 
            // in some cases Parent will not be set before the check is required.
            var entryAssembly = Assembly.GetEntryAssembly();
            if (entryAssembly == null)
                return true;

            return false;
        }
    }
wallismark
Can someone else comment on whether such a thorough check for DesignMode is actually necessary? Seems like it would cause a slight performance penalty.
Sören Kuklau
Weird... never happened to me.
Daniel Dolz
A: 

Another piece of good practice, do not delete default form constructors. IDE uses them, even when your logic do not. Locking is also useful.

Daniel Dolz