4

A WinForms form that includes a UserControl throws an exception when I attempt to display it in design mode, but runs properly when the program is ran or debugged.

The designer says:

The variable 'fpInfoA' is either undeclared or was never assigned.
ResearchTool fMain.Designer.cs Line:282 Column:1 Call Stack
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.Error(IDesignerSerializationManager manager, String exceptionText, String helpLink) at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression) at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression) at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)

However, it looks like the variable is assigned as I would expect in InitializeComponent

private void InitializeComponent()
{
    // ... (Order of statements is same as in actual code) ...
    this.tpFpA = new System.Windows.Forms.TabPage();
    this.fpInfoA = new ResearchTool.FPInfo();
    // ...
    this.tpFpA.Controls.Add(this.fpInfoA); // THIS LINE BLOWS UP IN DESIGN MODE
}

Thoughts on how to track down this issue? For example, is there a way to debug initialization of the designer?

Eric J.
  • 147,927
  • 63
  • 340
  • 553

3 Answers3

7

One workaround in case you can't fix the issue, would be to surround the offending bits of code with checks for DesignMode.

As in:

private void InitializeComponent()
{
    ...
    if(!DesignMode)
    {
        this.fpInfoA = new ResearchTool.FPInfo();
    }
    ...
}

This can also speed it up a little bit if it's doing things that aren't needed in design mode and that are quite slow, like connecting to databases or similar.

Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
  • The trouble is not in InitializeComponent, it's that the designer later things that this.fpInfoA was not initialized. I'll update the question to be clear on that. – Eric J. Aug 16 '11 at 17:34
  • @Eric You can use the `if(!DesignMode)` anywhere in the `Form` so you can surround any code that gets called when you view the `Form` in the designer. Assuming that you don't actually need that code while in the designer of course. So I don't think your comment affect my answer unless I misunderstand. – Hans Olsson Aug 16 '11 at 17:55
  • I'm not trying to remove any code at all from design time. As far as I can see, all of the code _should_ run in the designer. The problem seems to be that fpInfoA is "magically" not assigned in design mode, even though there's clearly an assignment earlier in `InitializeComponents`. – Eric J. Aug 16 '11 at 23:36
2

As Hans Olsson said, this potentially could be resolved by checking for design-mode and disabling offending logic.

This error will also trigger if there is any issue with the constructor of your UserControl. If there is an exception caused when the designer instantiates your UserControl, the designer will fail. In my case, the failure resulted in the same "[...] is either undeclared or was never assigned" error.

For example, see the following user control:

public class MyUserControl : UserControl {

    public MyUserControl()
    {
        InitializeComponent();

        throw new Exception(); //Causes a designer error.
    }
}

Now, when observing the designer for a form that contains this MyUserControl, we will see something similar to the following:

Winforms Designer Error

I cannot say if the designer is like this for previous versions of Visual Studio; but as for Visual Studio 2017, you can clearly see what happened.

The designer failed because a System.Exception was thrown. As a result, the variable [REDACTED] was thought to be undeclared or never assigned when in fact the auto-generated designer code was correct. The issue was with the MyUserControl's constructor.

Now, if you need to put logic that depends on external services/resources inside the control's constructor, you need to indicate that it should only occur during runtime. Alternatively, you can provide mock-up resources for design-time.

To do this, you can use the LicenseManager and check its current UsageMode. The modified code below only throws the exception in runtime now, and the designer doesn't have the error anymore.

public class MyUserControl : UserControl {

    public MyUserControl()
    {
        InitializeComponent();

        if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
        {
            throw new Exception(); //No longer fails in design-time.
        }
    }
}
Roman Pokrovskij
  • 9,449
  • 21
  • 87
  • 142
Nicholas Miller
  • 4,205
  • 2
  • 39
  • 62
1

You will find the information on how to trace design time code execution at:

What information do you need to fix a problem, which occurs with your products at design time?

platon
  • 5,310
  • 1
  • 22
  • 24
  • That link seems to deal with debugging a crashed instance of VS. In my case VS is not crashing, it's just showing an error message instead of the design view. – Eric J. Aug 16 '11 at 17:39
  • you will catch the exception if you follow the instructions from this link. I think that this is what you need. You will be able to set a breakpoint and debug your code. Try this, I used this technique multiple times and it works. – platon Aug 16 '11 at 18:48
  • Yep that did it. The user control's initialization code was throwing an Exception in design mode, and that Exception was not being reported by VS. – Eric J. Aug 16 '11 at 23:42