Исключение Конструктора WinForms
Форма WinForms, включающая UserControl, создает исключение, когда я пытаюсь отобразить ее в режиме конструктора, но работает правильно, когда программа запущена или отлажена.
Дизайнер говорит:
FpInfoA переменной '' либо недекларированных или никогда не был назначен.
ResearchTool fMain.Дизайнер.строка cs: 282 столбец: 1 Стек Вызовов
в системе.ComponentModel.Дизайн.Сериализация.CodeDomSerializerBase.Ошибка (менеджер IDesignerSerializationManager, строка exceptionText, строка helpLink) в системе.ComponentModel.Дизайн.Сериализация.CodeDomSerializerBase.DeserializeExpression (менеджер IDesignerSerializationManager, имя строки, выражение CodeExpression) в системе.ComponentModel.Дизайн.Сериализация.CodeDomSerializerBase.DeserializeExpression (менеджер IDesignerSerializationManager, имя строки, выражение CodeExpression) в системе.ComponentModel.Дизайн.Сериализация.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager менеджер, заявление CodeStatement)
Однако, похоже, что переменная назначена так, как я ожидал бы в 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 ответа:
Один обходной путь в случае, если вы не можете исправить проблему, будет заключаться в том, чтобы окружить оскорбляющие биты кода проверками на
DesignMode
.Как в:
private void InitializeComponent() { ... if(!DesignMode) { this.fpInfoA = new ResearchTool.FPInfo(); } ... }
Это также может немного ускорить его, если он делает вещи, которые не нужны в режиме разработки и которые довольно медленные, например, подключение к базам данных или тому подобное.
Как сказал Ханс Ольссон , это потенциально можно решить, проверив режим проектирования и отключив нарушающую логику.
Эта ошибка также сработает, если есть какие-либо проблемы с конструктором вашего
UserControl
. Если при создании экземпляраUserControl
конструктором возникнет исключение, то он завершится ошибкой. В моем случае неудача привела к тому же " [...] либо не объявлена, либо никогда не назначалась " ошибка.Например, см. пользовательский контроль:
Теперь, наблюдая за конструктором для формы, содержащей этоpublic class MyUserControl : UserControl { public MyUserControl() { InitializeComponent(); throw new Exception(); //Causes a designer error. } }
MyUserControl
, мы увидим нечто подобное следующему: Я не могу сказать, похож ли конструктор на предыдущие версии Visual Studio; но что касается Visual Sutdio 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. } } }