4
votes

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?

3

3 Answers

7
votes

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.

1
votes

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?

1
votes

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.
        }
    }
}