Исключение WinForms Designer - PullRequest
       19

Исключение WinForms Designer

3 голосов
/ 16 августа 2011

Форма WinForms, которая включает в себя UserControl, выдает исключение, когда я пытаюсь отобразить ее в режиме разработки, но работает правильно, когда программа запускается или отлаживается.

Дизайнер говорит:

Переменная 'fpInfoA' либо необъявлена, либо никогда не назначалась.
ResearchTool fMain.Designer.cs Строка: 282 Столбец: 1 стек вызовов
в System.ComponentModel.Design.Serialization..CodeDomSerializerBase.менеджер, имя строки, выражение CodeExpression) в System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement (IDesignerSerializationManager manager, CodeStatemeоператор nt)

Однако похоже, что переменная назначена так, как я ожидал бы в 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
}

Мысли о том, как отследить эту проблему?Например, есть ли способ отладки инициализации конструктора?

Ответы [ 3 ]

5 голосов
/ 16 августа 2011

Один из обходных путей, если вы не можете решить проблему, - это окружить биты кода, вызывающие проблемы, проверками на DesignMode.

Как в:

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

Это также может немного ускорить процесс, если он выполняет действия, которые не нужны в режиме разработки и выполняются довольно медленно, например подключение к базам данных или подобное.

1 голос
/ 16 августа 2011

Информацию о том, как отслеживать выполнение кода времени проектирования, можно найти по адресу:

Какая информация необходима для устранения проблемы, которая возникает с вашими продуктами во время разработки?

0 голосов
/ 07 ноября 2017

Как сказал Ханс Олссон , это потенциально можно решить, проверив режим проектирования и отключив логику-нарушитель.

Эта ошибка также сработает, если возникнет какая-либо проблема с конструктором вашего UserControl. Если при создании экземпляра UserControl возникнет исключение, то дизайнер потерпит неудачу. В моем случае ошибка привела к тому, что "[...] либо не объявлено, либо ему никогда не было присвоено" ошибка.

Например, см. Следующий пользовательский элемент управления:

public class MyUserControl : UserControl {

    public MyUserControl()
    {
        InitializeComponent();

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

Теперь, наблюдая за дизайнером формы, которая содержит это MyUserControl, мы увидим нечто похожее на следующее:

Winforms Designer Error

Я не могу сказать, похож ли конструктор на предыдущие версии Visual Studio; но что касается Visual Studio 2017, вы можете четко видеть, что произошло.

Конструктор не удался, потому что System.Exception было брошено. В результате переменная [REDACTED] считалась необъявленной или никогда не присваивалась, хотя на самом деле автоматически сгенерированный код конструктора был верным. Проблема была с конструктором MyUserControl.

Теперь, если вам нужно поместить логику, которая зависит от внешних служб / ресурсов, в конструктор элемента управления, вам нужно указать, что это должно происходить только во время выполнения. Кроме того, вы можете предоставить макетные ресурсы для времени разработки.

Для этого вы можете использовать LicenseManager и проверить его текущий UsageMode. Измененный код ниже генерирует исключение только во время выполнения, и у дизайнера больше нет ошибки.

public class MyUserControl : UserControl {

    public MyUserControl()
    {
        InitializeComponent();

        if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
        {
            throw new Exception(); //No longer fails in design-time.
        }
    }
}
...