views:

211

answers:

2

Hello!

Background: I have created this UserControl. In the constructor of the user control I call a function that retrieves some values from the database. If an error occurs while retrieving the values a messagebox explaining the error is shown. So far so good.

The Problem: I have created a form that (among other elements) includes my UserControl. Now when I open this form (or even the UserControl itself) the constructor is called (I suppose so it can be drawn accurately) and, because the database is unavailable, the messagebox (explained above) is shown.

How do I prevent this from happening?

I just want to be clear: the code works great in runtime. Everything is as designed. It is only in Designer view of Visual Studio (2008 SP1 if it matters) where the problem occurs. However in Designer it is awful, especially now when the application attempts to reconnect when the connection fails. Every time I go in to Designer mode my Visual Studio freezes for about 20 seconds (timeout of the reconnect) and it is killing my work process.

+1  A: 

I get around this by having a global static property on my Program class called IsRunning.

When my program starts up in the main method I set the IsRunning property to true. Then in the constructor of my user control I am able to poll the property IsRunning to determine whether or not I execute particular code, in your case code that would attempt to access a database...

EDIT: Here is some code...

private static bool _running = false;

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="Program"/> is running.
    /// This property is used for design time WSOD issues and is used instead of the 
    /// DesignMode property of a control as the DesignMode property has been said to be
    /// unreliable.
    /// </summary>
    /// <value><c>true</c> if running; otherwise, <c>false</c>.</value>
    public static bool Running
    {
        get
        {
            return _running;
        }
    }


    static void Main(string[] args)
    {
        Initialize();


        _running = true;

....

In my user control...

    public AssignmentList()
    {
        InitializeComponent();

        if (!Program.Running)
        {
            return;
        }
Wil P
Any reason why you're not using the "DesignMode" property?
longeasy
Instead of this, handle the Load event, move your code into it and check the DesignMode property. Much better solution than some tightly coupled global variable.
Brian Ensink
It's been a while since I have thought about this, however I think there was some weirdness with the DesignMode properly so I just wanted to put myself into control with a simple (no magic) kinda method. I'm not 100%, but I don't think the DesignMode property is actually set on your control until after the constructor fires.
Wil P
The DesignMode property is not unreliable ... you just can't check it in the constructor. Think about it: the VS designer is going to instantiate your form class, then in perhaps the very next line of code its going to set DesignMode=true.
Brian Ensink
Yea I hear you, that makes sense. It was prolly a hack on my looking back on how I used the method above because at the time I did not think about why it was working the way it was. Thanks for setting me straight.
Wil P
@wilpeck You're welcome. I remember having problems with this when I started with .NET forms before I fully understood Load and DesignMode.
Brian Ensink
+4  A: 

You could check whether your control is displayed in design mode:

http://msdn.microsoft.com/en-us/library/system.componentmodel.component.designmode.aspx

/Edit: As people pointed out in the comments to another answer, the DesignMode property is not usable in the constructor. So the best solution would probably be to move the database stuff into an event like "Load" and use the DesignMode property there.

longeasy
+1, This is a much better solution than a global variable.
Brian Ensink
I agree this would be a more general solution than a global variable, however I still accepted wilpeck's answer, because it is more helpful in my case. I have all the error-reporting stuff in a separate class, and now I only check the global variable in that class instead of doing it in each control.
Rekreativc