Click here to Skip to main content
Click here to Skip to main content

How to avoid WSODs in the Visual Studio 2005 Designer

By , 3 Apr 2006
 

Sample Image - 01 article.jpg

Introduction

This article explains how to tackle one of the most dreadful situations Windows Forms developers encounter during their daily work - WSODs.

Background

The term WSOD (White Screen of Darn) was set by Microsoft employees in an MSDN blog.

Using the code

Imagine the following scenario. One morning you arrive at your workplace, turn your monitor on, and then try to open a form in your application that builds and runs perfectly well, and instead of seeing your handcrafted form, you see a big frightening screen with the following title in red, and a big X near it:

One or more errors encountered while loading the designer. The errors are listed below. Some errors can be fixed by rebuilding your project, while others may require code changes.

As a pretty fresh GUI developer, but a pretty experienced software developer all-in-all, I was pretty astonished when I first encountered this phenomenon. My coworkers were not as surprised as I was, but still solving this sort of a problem never seemed to be trivial.

Explaining the problem

When the Visual Studio Designer views forms, it runs the constructor of your code. However, the code may behave in an unexpected way when run out of the application context. This may result in some exceptions thrown. The Visual Studio Designer does not like those exceptions, and may show a screen similar to this one, instead of the screen you really wanted to see:

About the example

My example code consists of a form called MainForm. This form contains a user control called SevenHolder. The SevenHolder user control has nothing but a text box, whose content is updated from a singleton. The singleton class holding this information, simply called Singleton, holds an integer, which seems always to be 7. However, another singleton class called Global, limits the creation of the Singleton instance only to the time when the application is running. The Global instance is created as the first thing in this program, in Program.cs, where its Running attribute is set to true. Since SevenHolder updates the text box in the constructor, but the constructor will only obtain the Singleton instance on runtime, an exception will be thrown when the code is run in design-time.

The solution

Finding this sort of problems may prove very difficult by only reviewing the code. However, an easy solution exists. By taking the following steps, you may find the exact location of the code causing the exception, thus making it possible to change it in a way that the Designer works well with it:

  1. Open a new Visual Studio instance.
  2. Open any source file. This is required so that Visual Studio lets you attach to a process.
  3. Attach the new Visual Studio instance to the first one. The Visual Studio process is called devenv.exe. You only need to attach to managed code. Set Visual Studio to break on Common Language Runtime exceptions - Thrown and User-handled.
  4. Close the problematic form, and reopen it.
  5. This should result in an exception caught inside your code in the second instance of Visual Studio!

    In our case, the following code was causing the problem:

    this.labelSevenHolder.Text = sing.Information.ToString();

    In order to fix it, two approaches may be taken. The first one is to check the value of sing before using it:

    public SevenHolder()
    {
        InitializeComponent();
    
        Singleton sing = Singleton.Instance();
    
        if (sing != null)
        {
            this.labelSevenHolder.Text = sing.Information.ToString();
        }
    }

    The second approach is to check the value of the DesignMode property inherited from System.ComponentModel.Component to see whether the application is indeed running before doing anything useful. This check should always be performed after the call to InitializeComponent though, otherwise your control may not render correctly in design-time:

    public SevenHolder()
    {
        InitializeComponent();
    
        if (this.DesignMode)
            return;
    
        Singleton sing = Singleton.Instance();
    
        this.labelSevenHolder.Text = sing.Information.ToString();
    }

    And of course, the complete code should look like this:

    public SevenHolder()
    {
        InitializeComponent();
    
        if (this.DesignMode)
            return;
    
        Singleton sing = Singleton.Instance();
    
        if (sing != null)
        {
            this.labelSevenHolder.Text = sing.Information.ToString();
        }
    }
  6. After recompiling the code, reopening MainForm should result with the form. In this case, it does not look exactly in design-time as the form in run-time, because, of course, the content of the label inside the user control is only known to the application in run-time.

Points of Interest

Investigating this sort of problems really makes one understand how the Visual Studio designer works under-the-hood.

History

  • Minor fixes: 31/3/2006.
  • Initial version: 28/3/2006.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

nadav74
Software Developer (Senior)
Israel Israel
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralI don't even get a WSOD anymore...memberprimem0ver14 Mar '11 - 18:04 
I don't even get a WSOD. Well... it is white. But all I have seen since reinstalling Visual Studio 2005 (fresh) on my fresh install of Windows 7 is a single line of HTML code. (AND YES... I did download the Service Packs and Vista/7 updates!). It doesn't even seem to be reading it as a web page but as simple text. I spent 4-5 hours fixing a problem with a form because I forgot that the WSOD actually does give a clue the problem at least. But I didn't even see the error amongst all the HTML formatting code.
 
In an attempt to avoid another 4-5 hour of complete frustration I read the line very carefully and suddenly remembered that the HTML is supposed to be rendered as the WSOD and tell you something about the problem. So I searched online for a way to get the WSOD to display correctly to no avail. But I did find this article. Does anyone know how to get Visual studio render the WSOD page correctly?
 
Honestly... I hate VS 2005. Every time I install it I get a different bug where it is supposed to do something and doesn't. Why? The particular issue worked right the last time I installed it!!!
 
Meanwhile... I guess I will follow this procedure to find the problem. Thanks!
GeneralSuggestion:membersherifffruitfly24 May '09 - 8:57 
Get the process ID of the VS instance you want to be the debugEE, before opening a 2nd (or 3rd or 4th...) instance of VS to be the debugER.
GeneralMore info on thismembertonyt10 Dec '08 - 6:27 
I have come across a number of WSODs that were not solved by the solutions shown here.
 
Even the test to see if you are running in the IDE (looking at the process name) did not solve it.
 
I finally discovered why that's so.
 
In my case, code that is jitt'ed in the IDE was referencing types from a DLL that could not be loaded into Visual Studio. So, the solution to the problem was't preventing code from executing in the IDE, the solution was to prevent code from being jitted in the IDE. The IDE will jit all code that is called from a constructor, on a per-method basis.
 
Hence, if you have a test that checks to see if you are running in the IDE and the tests indicates you are not, and call code like this:
 
   
   public class MyControlClass : UserControl
   {
      public MyControlClass()
      {
         if( ! IsVisualStudio() )
         {
             Foo foo = new Foo(); // Foo is in a DLL that can't be loaded in IDE
         }
      }
   }
 
In the above, the IsVisualStudio() method returns true if you are running in the IDE (by looking at the current process name), and the Foo instance is not created when you are in the IDE.
 
Even though the the Foo type is not instantiated at design time, the code for the entire method is jitted, and that's what causes the WSOD.
 
The solution is to put any code that references types which cannot be jitted at design time in a seperate method, and then call that method via reflection. You have to call the method via reflection because if you call it directly from the constructor, it will be jitted as well.
 
   
   public class MyControlClass : UserControl
   {
      public MyControlClass()
      {
         if( ! IsVisualStudio() )
         {
             MethodInfo m = this.GetType().GetMethod("runtimeOnly", BindingFlags.Instance|BindingFlags.NonPublic)
             m.Invoke( this, null );             
         }
      }
 
      // not called directly from constructor, so it will
      // not be jitted at design time.

      void runtimeOnly()
      {
         Foo foo = new Foo();
         // use foo here.
      }
   }
 

 
HTH
GeneralWorks great for WPF too!memberKenrae4 Nov '08 - 21:59 
Thanks! I had this problem in a WPF application. Your method can be used with WPF apps too.
GeneralRe: Works great for WPF too!membernadav744 Nov '08 - 22:02 
Thanks for your reply, it's great to know this article is still useful despite the evolution in technology.
GeneralDesigner View problemmemberramki_mars15 May '08 - 18:28 
Hi ,
 
when am trying to open designer view for a form which is inheriting BaseViewForm getting white screen with this message:
 
One or more errors encountered while loading the designer. The errors are listed below. Some errors can be fixed by rebuilding your project, while others may require code changes.
 
Could not load file or assembly 'Wrappers.CLI, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Hide
 
at MYnamespace.BaseViewForm..ctor()
 

Observatrions:
1. In C# project I added a reference to Wrappers.CLI.dll( This Project VC++ project Wrapper one which makes contact from C# code to c++ code)
Wrappers.CLI version is 1.0.0.1 but when I added reference to this the VS shows the version as 0.0.0.0 (By looking at properties after adding reference)

So suspected the variables from Wrappers.CLI.dll which declared in C# form (which is being opened in design view) may cause the error.
 
2. I created another BaseViewFormNew without having code related to Wrappers.CLI.dll and made to use this Base form instead of earlier BaseViewForm (which contains code related to Wrappers.CLI.dll then this forms gets opened. This approach worked fine. Then once anyof the forms design view is opened am reverting abck to inherit using older BAseViewForm then surprisingly the design view is getting opened Roll eyes | :rolleyes: . But this works in one machine in other machines this is not working. So what would be the solutions? No idea.
 
I tried
 
1. rebuilding, Clean and rebuilding, deleting bin,obj files
2. steps in http://www.codeproject.com/KB/cs/wsod.aspx
3. Deleting cache fiels from Project Assemblies folder
 
but none was working..Confused | :confused:
 
Thanks,
Ramki
GeneralProblem in viewing designer of windows form c#memberramki_mars11 Apr '08 - 1:17 
Hi,
 
Am getting the problem while viewing the designer of the
windows form (developed in C#)
 
C# project has references to wrapper classes(to contact with C++
classes).
 

Error :
 
One or more errors encountered while loading the designer. The errors
are listed below. Some errors can be fixed by rebuilding your project,
while others may require code changes.
 

Could not load file or assembly Wrappers.CLI, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null' or one of its dependencies. The
system cannot find the file specified.
Hide
 

at BaseClass..ctor()

 

The reference had been added through project browse folder only.
 
I tried using the steps given in the article but could not get the exact line of code where it was giving this exception.
 

 
Thanks,
Ramki
GeneralAnother simple way to debug this type of errormemberNatza Mitzi23 Dec '07 - 1:45 
Use Debug.Assert either in a catch clause or as a conditional statement
The assertion works even in design mode.
 
try
{
}
catch(Exception err)
{
      Debug.Assert(false,err.Message);
}
 
or
 
Debug.Assert(text != null,"The text is noll");
Natza Mitzi
GeneralRe: Another simple way to debug this type of errormemberSerialHobbyist8 Mar '09 - 1:27 
Thanks for this tip, Natza. I tried what the OP suggested but I couldn't work out how to set this bit:
 
"Set Visual Studio to break on Common Language Runtime exceptions - Thrown and User-handled"
 
but your suggestion worked a treat and has saved me hours of head-scratching and teeth-gnashing.
 
SH Wink | ;)
Generalthis.DesignModememberJakub Mller14 Aug '07 - 21:19 
Hi, thanks for good article!
 
But, there is littlebite mistake.
 
The body of DesignMode property looks like this:
protected bool DesignMode {
    get {
        bool result = false;
        ISite site = this.Site;
        if ( site != null ){
            result = site.DesignMode;
        }
 
        return result;
    }
}
 
What it mean? The DesignMode property in constructor always returns False!
 
------
 
There is next tricky question.
 
If you have this classes:
MyTextBox // derives from TextBox
MyUserControl // derives from UserControl and contains one or more controls "MyTextBox"
MainForm // derives from Form and contains one or more controls "MyUserControl"
 
The Visual Studio Designer sets the Site property only to controls added in designed control/form, but not to controls inside. So, if you open the designer for MainForm the instances of MyUserControls will have the DesignMode set to True bud the instances of MyTextBox will have the DesignMode always set to False.
 

The solution is the helper class with simple method IsInDesignMode which looks like this:
public static class MyHelperClass {
    // Returns True, if specified control or one of their parent control is in design mode.
    public static bool IsInDesignMode( Control control ) {
        if ( control == null ) { throw new ArgumentNullException( "control" );
 
        bool result = false; // return value
        Control ctl = control; // checked control for design mode
        do {
            ISite site = ctl.Site; // get the site object, which is set by designer
            if ( site != null ) {
                result = site.DesignMode; // check for design mode
                if ( result ) { break; } // if control is in design mode then loop ends
            }
        } while ( ( ctl = ctl.Parent ) != null ); // track the parent control

        return result;
    }
}
 
Then the using in the custom/user control should looks like this:
public class MyTextBox : TextBox {
    public MyTextBox() {
        ...
        // avoid any code which potentialy throws exception(s)
    }
 
    protected override void OnLoad( EventArgs e ) {
        base.OnLoad( e );
 
        if ( MyHelperClass.IsInDesignMode( this ) == false ) {
            // some code which potentialy throws exception(s)
        }
    }
}

 
/* Geniality is in simplicity. */

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 3 Apr 2006
Article Copyright 2006 by nadav74
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid