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?

Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
Sören Kuklau
  • 19,454
  • 7
  • 52
  • 86
  • I saw this happen a looooooong time ago that if I did not let Visual Studio render the form completely, it would drop some controls. This was probably the earliest editions of Visual Studio. – Raj More Apr 20 '10 at 18:40
  • Your last paragraph is very interesting. An exception could happen in the associated designer of a control while creating code (the designer does not do this itself) and this could interrupt the code generation process. So, the culprit could be the control designer that is _before_ the disappearing control. I had this problem in VS in the past but could not find an explanation. – Timores Apr 20 '10 at 18:43
  • 1
    I don't think that having runtime only code in the eventhandlers could be the reason, a previous project I took over was littered with DB reads in the Load handlers and until I put it a lot of "If not DesignMode Then" it kept having problems all the time when I opened them in the designer, but it never lost any controls from that as I noticed. – Hans Olsson Apr 20 '10 at 18:53
  • I just remembered that I have had something this happen with a custom controls when I've added the controls to a form but later broken them so they won't build, and when I fix them they're gone from the form. I've never been able to reproduce that consistently though so I can't say for sure that it's not something I've done wrong that made that happen. – Hans Olsson Apr 20 '10 at 19:00
  • Does the Infragistics control's code get generated into the same designer file? I can't imagine what a challenge the winform's team had in generating procedural code and also considering all the scenarios where something else mucks with that code. This probably half the reason for the introduction of something more declaritive like XAML. I always had problems with the Dataset designer having similar problems where changes through the designer would disappear or a dataset design would break altogether seemingly at random and have to be deleted and recreated. – AaronLS Apr 20 '10 at 19:02
  • "I just remembered that I have had something this happen with a custom controls when I've added the controls to a form but later broken them so they won't build, and when I fix them they're gone from the form. I've never been able to reproduce that consistently though so I can't say for sure that it's not something I've done wrong that made that happen." I didn't touch the code of that control today (when this happened), nor did anyone else, so that can't be it. "Does the Infragistics control's code get generated into the same designer file?" Yep. And yep, I bet that adds much complexity. – Sören Kuklau Apr 20 '10 at 19:08

6 Answers6

14

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
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Daniel Dolz
  • 2,403
  • 1
  • 18
  • 23
2

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
  • 160,644
  • 26
  • 247
  • 397
1

It is not a real answer for you, but here are some more pointers I've found helpful..

A) See @Daniel Dolz's answer. I wholeheartedly recommend you ALWAYS do what he's recommending 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 Windows Forms.

OK, sometimes you have to, but it's not someplace to do regular development. Third-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 Windows Forms project for more than two years immediately prior to my current project, and all I can say is until we put an end to people 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 because we're so used to editing markup, but the designer.cs isn't the same as markup.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jim L
  • 2,297
  • 17
  • 20
1

I've found the DesignMode property sometimes produces an unexpected result (Daniel's answer). 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: I am not 100% sure about this one; I 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;
        }
    }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
wallismark
  • 1,766
  • 2
  • 21
  • 35
0

I've seen this happen with Visual Basic 6.0 and early .NET when the OS was having problems. We had to do a reboot and repair.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dave
  • 1,234
  • 13
  • 24
0

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
  • 2,403
  • 1
  • 18
  • 23