Устранение неполадок, возникающих в режиме разработки
Обновлен: Ноябрь 2007
Ниже перечислены наиболее распространенные проблемы, которые могут возникать при создании использовании настраиваемого поведения времени разработки для компонентов и элементов управления Windows Forms:
Не удается выполнить отладку в режиме разработки.
Ошибка компилятора: "Не удается найти тип или пространство имен "имя типа"".
Ошибка времени разработки: "Не удается создать компонент "имя компонента"".
Ошибка отладки: "Недопустимая межпотоковая операция: Обращение к элементу управления "имя элемента управления" осуществляется не из того потока, в котором он был создан".
Ошибка времени разработки: "Не удается открыть конструктор файла, так как класс этого файла не является наследником класса, поддерживающего визуальную разработку".
После удаления компонента остаются глифы.
Поведение конструктора по умолчанию нарушается настраиваемым поведением.
События конструктора создаются непредвиденным образом.
Сбой сериализации коллекций.
Конструктору не удается получить ссылку на объект UndoEngine.
Среда разработки не распознает изменения в свойствах компонента.
Синтаксис DesignerAttribute.
Обновление среды разработки после внесения изменений в компонент или конструктор.
Предупреждение FxCop для только что созданной формы Windows Forms: DoNotInitializeUnnecessarily.
Разделяемые классы и конструктор Windows Forms.
Устаревшие пользовательские элементы управления вызывают неожиданное поведение конструктора.
Смарт-тег в размещенном конструкторе вызывает исключение.
Значок компонента не отображается в панели элементов.
Не удается выполнить отладку в режиме разработки.
Существует два способа отладки кода в режиме разработки:
Размещение вызовов MessageBox.Show в самых важных местах кода.
Присоединение другого экземпляра Visual Studio для отладки среды разработки первого экземпляра.
Дополнительные сведения см. в разделе Практическое руководство. Обращение к службам времени разработки.
Topic | Location |
---|---|
Пример. Отладка пользовательских элементов управления Windows Forms во время разработки | Элементы управления Windows Forms |
Разрешение вопросов, связанных с созданием элементов управления и компонентов | Элементы управления Windows Forms |
Пример. Отладка пользовательских элементов управления Windows Forms во время разработки | dv_mclictl |
Разрешение вопросов, связанных с созданием элементов управления и компонентов | dv_mclictl |
Ошибка компилятора: "Не удается найти тип или пространство имен "имя типа""
Необходимо добавить ссылку на сборку System.Design. Связанные с конструктором типы размещены в сборке System.Design. К ним относятся типы в пространствах имен System.Windows.Forms.Design и System.ComponentModel.Design.
Кроме того, необходимо импортировать требуемые пространства имен с помощью ключевых слов Imports или using. Дополнительные сведения см. в разделе Практическое руководство. Доступ к поддержке во время разработки в Windows Forms.
Ошибка времени разработки: "Не удается создать компонент "имя компонента""
Эта ошибка может возникнуть при создании компонента или элемента управления из панели элементов в рабочей области конструирования. В следующей таблице представлены две вероятные причины этой ошибки.
Причина |
Описание |
Примечания |
---|---|---|
Отсутствие конструктора по умолчанию |
Компонент или элемент управления должен иметь конструктор по умолчанию, то есть конструктор, не содержащий параметров. |
Конструктор по умолчанию нужен среде разработки для обеспечения возможности создания экземпляра пользовательского типа. |
Компонент является универсальным типом |
Пользовательский компонент или элемент управления не может иметь универсальный тип; такие типы также называются шаблонными или параметризованными типами. Среда разработки не поддерживает универсальные типы. |
Если универсальный тип является производным от класса UserControl и запускается в контейнере для тестирования пользовательских элементов управления Visual Studio, появится следующее сообщение об ошибке: Не удалось создать пользовательский элемент управления имя Хотя пользовательские компоненты и элементы управления не могут относиться к универсальным типам, они могут использовать универсальные типы. |
Ошибка времени разработки: "Значение не может быть нулевым. Имя параметра: "имя компонента""
Эта ошибка может возникнуть при создании компонента или элемента управления из панели элементов в рабочей области конструирования. Самой вероятной причиной ошибки является использование компонента или элемента управления, который при построении которого была выбрана 64-разрядная версия целевой сборки. Среда разработки Visual Studio не поддерживает 64-разрядные компоненты.
Ошибка отладки: "Недопустимая межпотоковая операция: Обращение к элементу управления "имя элемента управления" осуществляется не из того потока, в котором он был создан".
При использовании многопоточности в приложениях Windows Forms следует с особой осторожностью обращаться к элементам управления, придерживаясь правил поточной безопасности. Это исключение создается отладчиком и не появляется во время выполнения, но эту проблему настоятельно рекомендуется устранить сразу же, как только она появилась. Дополнительные сведения см. в разделе Практическое руководство. Осуществление потокобезопасных вызовов элементов управления Windows Forms..
Ошибка времени разработки: "Не удается открыть конструктор файла, так как класс этого файла не унаследован от класса, поддерживающего визуальную разработку"
Файл, содержащий пользовательский компонент или элемент управления, может содержать определения нескольких классов, но первый класс в файле должен поддерживать возможность использования в конструкторе. Первый класс в файле должен реализовывать интерфейс IComponent либо быть производным от класса Component или класса-наследника Component.
После удаления компонента остаются глифы.
Если пользовательский конструктор создает объекты Adorner, следует удалять их из рабочей области конструирования, когда конструктор выходит из области действия. Вызовите в методе конструктора Dispose метод BehaviorServiceAdornerCollection.Remove, чтобы удалить объекты Glyph, а также связанные с ними объекты Adorner и Behavior. Дополнительные сведения см. в разделе Практическое руководство. Расширение внешнего вида и функциональности элементов управления в режиме конструктора.
Поведение конструктора по умолчанию нарушается настраиваемым поведением.
Конструктор элементов управления по умолчанию создает глиф, покрывающий весь элемент управления в рабочей области конструирования. Этот глиф называется основным. Если пользовательский конструктор элемента управления создает глиф с теми же границами, что и у основного глифа, он скроет базовую реализацию поведения Behavior, связанную с основным глифом. Это приведет к тому, что не будут отображаться функциональные элементы по умолчанию — например, смарт-теги и глифы изменения размера.
Передавать сообщения между объектами Behavior нельзя, поэтому невозможно будет обрабатывать сообщения мыши и передавать их базовым объектам Behavior. При реализации глифа, перекрывающего весь элемент управления, пользователь целиком несет ответственность за состояние и поведение пользовательского конструктора.
События конструктора создаются непредвиденным образом.
Если пользовательский конструктор присоединяет обработчики событий к событиям конструктора, таким как ComponentRemovedActiveDesignerChanged и SelectionChanged, эти обработчики событий необходимо отсоединять в методе Dispose конструктора.
Невыполнение данного условия может привести к непредвиденному поведению во время разработки. В следующем списке перечислены некоторые возможные симптомы:
Окно сообщения об ошибке: "Ошибка при обработке этой команды".
Окно сообщения об ошибке: "В экземпляре объекта не задана ссылка на объект".
Обработчики событий вызываются неправильно при удалении компонентов или закрытии конструкторов.
Сбой сериализации коллекций.
Если для свойства-коллекции пользовательского компонента или элемента управления требуется сериализация, следует использовать атрибут DesignerSerializationVisibilityAttribute со значением Content. Дополнительные сведения см. в разделе Практическое руководство. Сериализация коллекций стандартных типов с использованием атрибута DesignerSerializationVisibilityAttribute.
Конструктору не удается получить ссылку на объект UndoEngine
При попытке получения ссылки на службу UndoEngine в ходе загрузке формы, метод GetService возвращает значение null.
Служба UndoEngine не создается и не является активной до окончания загрузки формы. После загрузки формы последующие вызовы GetService возвращают ссылку UndoEngine.
Обычно прямая ссылка на объект UndoEngine не требуется. Случаи, в которых возникает необходимость в этой ссылке, обычно обусловлены действием пользователя и возникают после загрузки конструктора.
Среда разработки не распознает изменения в свойствах компонента.
Среда разработки не распознает изменения в пользовательских компонентах или элементах управления при установке свойств напрямую. Для возникновения таких событий, как ComponentChanged, необходимо задавать значение свойств компонента с помощью метода PropertyDescriptor.SetValue. При этом среда разработки уведомляется об изменении свойства, благодаря чему рабочая область конструирования и элементы управления PropertyGrid могут обновиться правильно. Дополнительные сведения см. в разделе Практическое руководство. Расширение внешнего вида и функциональности элементов управления в режиме конструктора.
Синтаксис DesignerAttribute
Пользовательский конструктор связывается с конструируемым им элементом управления с помощью атрибута DesignerAttribute, применяемого к элементу управления.
Параметры DesignerAttribute следует задавать точно; в противном случае среда разработки не загрузит пользовательский конструктор.
Обновление среды разработки после внесения изменений в компонент или конструктор.
При внесении изменений в те части компонента, которые используются во время конструирования, необходимо повторно построить проект компонента. Кроме того, если открыт другой проект Windows Forms, использующий данный компонент, то для отображения изменений, скорее всего, потребуется обновить проект. Обычно необходимо закрыть и повторно открыть окно конструирования, в котором содержится компонент.
Предупреждение FxCop для только что созданной формы Windows Forms: DoNotInitializeUnnecessarily.
Конструктор Windows Forms создает следующий код для проектов приложений Windows Forms на языке С#.
private System.ComponentModel.IContainer components = null;
В зависимости от действующих правил FxCop, FxCop может выдавать предупреждение "DoNotInitializeUnnecessarily". Это обусловлено тем, что значением по умолчанию для ссылочных свойств в среде CLR является значение null.
Если конструктор не инициализирует поле components значением null, компилятор C# выдает следующее предупреждение:
"Полю "Form1.components" нигде не присваивается значение, поэтому оно всегда будет иметь значение по умолчанию null".
Можно отключить это предупреждение FxCop с помощью атрибута SuppressMessageAttribute, но это может привести к проблемам в обслуживании, если имя класса будет изменено. Поэтому рекомендуется пропустить это предупреждение FxCop.
Разделяемые классы и конструктор Windows Forms.
По умолчанию конструктор Windows Forms сохраняет код сериализации конструктора в выделенном файле, отделенном от основного файла компонента. Так, например, в проекте приложения Windows Forms определение класса Form1 делится на два файла, как показано в следующей таблице.
Файл (имена файлов С#) |
Функция |
---|---|
Form1.cs |
Основной файл класса |
Form1.Designer.cs |
Созданный конструктором код |
Файл (имена файлов VB) |
Функция |
---|---|
Form1.vb |
Основной файл класса |
Form1.Designer.vb |
Созданный конструктором код |
Обычно нет необходимости модифицировать код, созданный конструктором Windows Forms. Вместо этого изменяется основной файл класса.
Конструктор Windows Forms использует ключевое слово partial для разделения реализации Form1 на два отдельных файла. Это позволяет избежать смешения пользовательского кода с кодом, созданным конструктором. Дополнительные сведения о ключевом слове partial см. в разделах Разделяемые классы и методы (Руководство по программированию в C#) и Partial (Visual Basic).
Конструктор Windows Forms не поддерживает разделение определения конструируемого типа более чем на две реализации с ключевым словом partial. Это ограничение также распространяется на создание нового файла класса, который содержит третью часть определения разделяемого класса, а также на добавление третьей части определения разделяемого класса как в основной файл, так и в файл конструктора. Члены, определенные таким образом, не будут доступны в конструкторе Windows Forms.
Устаревшие пользовательские элементы управления вызывают неожиданное поведение конструктора.
Когда типы в конструкторе становятся недействительны, служба ComponentSerializationService выполняет частичную перезагрузку для обновления типов в конструкторе. В версиях Visual Studio, предшествующих Visual Studio 2005, выполнялась полная перезагрузка конструктора. Частичная перезагрузка в Visual Studio 2005 быстрее, чем полная перезагрузка, а также сохраняет стек отмены.
Компоненты и соответствующие им сериализаторы, созданные в версиях, предшествующих Visual Studio 2005, могут не поддерживать частичную перезагрузку. Компоненты и элементы управления могут вызывать непредвиденное поведение, потому что они создавались в расчете на десериализацию только при полной перезагрузке. Среди симптомов можно указать переполнение стека, зависание или пустые области конструктора Windows Forms, в котором используются устаревшие элементы управления.
Можно вернуться к полной перезагрузке, добавив в файл devenv.exe.config приведенный ниже параметр. Если среда Visual Studio 2005 установлена в папке по умолчанию, полный путь будет выглядеть следующим образом: "C:\Program Files\Microsoft Visual Studio 8\Common7\IDE".
<appSettings>
<add key="EnableOptimizedDesignerReloading" value="false" />
</appSettings>
Смарт-тег в размещенном конструкторе вызывает исключение.
При размещении конструктора вне Visual Studio смарт-теги могут создавать исключения типа NullReferenceException. Чтобы устранить эту проблему, добавьте ссылку на IUIService в конструкторе и реализуйте свойство Styles. В коллекции IDictionary, доступной через свойство Styles, задайте новый шрифт Font в качестве элемента c ключом "DialogFont", как показано в следующем фрагменте кода.
Styles["DialogFont"] = new Font(...);
Значок компонента не отображается в панели элементов.
При использовании атрибута ToolboxBitmapAttribute для сопоставления значка с пользовательским компонентом в Visual Studio в панели элементов не отображается растровое изображение для автоматически созданных компонентов. Чтобы отобразить растровое изображение, перезагрузите элемент управления, используя диалоговое окно Выбор элементов панели элементов.
См. также
Задачи
Практическое руководство. Обращение к службам времени разработки
Основные понятия
Ошибки во время разработки в конструкторе Windows Forms Designer