Резюме
В этой статье приводится обзор статей на смежную тему, иллюстрирующих
основные понятия разработки элементов управления Microsoft Windows на
основе обсуждения и фрагментов кода. (7 печатных страниц)
Исходный код
WinFormControls.exe можно загрузить из MSDN Code Center.
Этот обзор открывает серию из пяти статей по разработке элементов
управления в Microsoft® .NET:
- Разработка пользовательских элементов управления Windows с
помощью Visual Basic .NET (обзор)
-
Добавление проверки правильности регулярного выражения
-
Объединение нескольких элементов управления в один
-
Расширение элемента управления TreeView
-
Рисование собственных элементов управления с помощью GDI+
Содержание
Введение
Одним из самых важных моментов маркетингового продвижения Microsoft®
Visual Basic® всегда была поддержка
компонентов, позволяющая третьим лицам разрабатывать визуальные элементы
управления (и, в конечном счете, невизуальные компоненты), которые
предоставляют разработчику Visual Basic новые функциональные
возможности. Этот аспект разработки Visual Basic привел к появлению
огромного числа как свободно распространяемых, так и коммерчески
распространяемых элементов управления. В конечном счете, новые
визуальные и невизуальные компоненты могли разрабатываться даже
непосредственно в Visual Basic, что привело к еще большему увеличению
числа элементов управления, многие из которых были созданы
разработчиками (и группами разработчиков) для своего собственного
пользования.
Примечание Переход от
используемых в настоящий момент элементов управления Microsoft ActiveX®
к Microsoft .NET не влечет за собой модернизацию или написание нового
кода. С помощью интегрированной среды разработки Microsoft Visual Studio®
.NET (в меню Tools выберите Customize Toolbox) или утилиты .NET
Framework
ActiveX Control Importer (Aximp.exe) элементы управления ActiveX
можно использовать из приложений .NET. Если какой-то определенный
элемент управления не работает в .NET, возможно, разработчик компонента
должен модернизировать его. При работе с элементами управления,
приобретенными у третьих лиц, проверьте наличие обновлений элемента
управления или версии .NET на Web-сайте поставщика.
В мире разработки .NET по-прежнему сохраняется потребность в
пользовательских компонентах UI, однако механизмы создания этих
компонентов изменились. В этой статье будут рассмотрены следующие
вопросы: как и для чего разрабатываются элементы управления Microsoft
Windows®, как разработка элементов
управления изменилась по сравнению с версиями Visual Basic 5.0 и 6.0;
также приведены четыре примера разработки элементов управления (каждый
из них рассматривается подробно в отдельной статье).
Для чего разрабатываются собственные элементы управления?
Если необходимо ограничить тип текста, который может быть набран в
Windows Form TextBox, в коде формы можно создать процедуру,
обрабатывающую
событие KeyPress. Затем в этой процедуре обработки событий можно
проверить нажатую клавишу и либо позволить ее, либо блокировать
результат нажатия:
Private Sub TextBox1_KeyPress(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyPressEventArgs) _
Handles TextBox1.KeyPress
If Not Char.IsDigit(e.KeyChar) Then
e.Handled = True
Else
e.Handled = False
End If
End Sub
Примечание Перехват
нажатия клавиш не обеспечивает ввод исключительно цифр, поскольку
пользователь может вставить значение в TextBox, или в TextBox могут
начать накапливаться недействительные данные. Другие события, такие как
TextChanged, имеют более широкие возможности, однако предпочтительнее
выполнить проверку с помощью событий Validating или Leave, когда
пользователь выходит из элемента управления для ввода данных. Проверка
только при выходе из элемента управления позволяет устранить немедленную
обратную связь, т.е. блокировку нажатия недопустимых клавиш, при этом
пользователь может вставить текст с "незначительными отклонениями",
например, "3425 2343 2342 2342", в поле, не допускающее пробелов, и
затем удалить их перед выходом из элемента управления.
Добавить код к событию элемента управления не очень трудно, однако
что может произойти при разработке более сложного кода, например, для
проверки достоверности почтового адреса или номера транспортного
средства? Вероятно, этот код будет использоваться в нескольких формах,
возможно, даже в нескольких проектах, или совместно использоваться с
другими разработчиками в группе. Распространение фрагментов кода из
данной формы наряду с рекомендациями по наименованию и установке
элемента управления будет нелегким. Разработка собственного элемента
управления позволит избежать всех проблем с распространением, поскольку
пользовательский интерфейс и связанный код объединяются в одном
компоненте, который можно распространять относительно просто. Обновление
функциональных возможностей этого элемента управления можно теперь
выполнять с помощью свободного распространения сборки данного
компонента, не рассылая новые фрагменты кода и не прося разработчиков
вставить новый код вместо старого.
Как изменилась разработка элементов управления под влиянием
наследования?
Разработка элементов управления в .NET в значительной степени
отличается от разработки в Visual Basic 6.0. Это сводится в основном к
возможности наследования в .NET. Разработка в Visual Basic 6.0 была
существенно ограничена рисованием и/или использованием комбинации других
элементов управления для создания требуемых функциональных возможностей.
Если требовалось создать пользовательское текстовое поле ввода,
описанное ранее в этой статье, было необходимо создать новый элемент
управления ActiveX, содержащий TextBox.
Примечание Этот процесс
часто называется включением и делегированием и фактически используется
также в классах, отличных от элементов управления, Visual Basic 6.0,
когда необходимо смоделировать наследование.
Если ожидаемые свойства TextBox (в частности, свойство Text) не
добавить в новый элемент управления, их в нем не будет. Кроме того,
будет необходимо добавить код, обеспечивающий заполнение TextBox'ом всей
области пользовательского элемента управления и обрабатывающий изменение
размеров. Конечно, этой цели можно достигнуть и с помощью
ActiveX Control Interface Wizard (Visual Basic 6.0 add-in, см. рис.
1), и это было бы несложно, однако тот же результат достигается в .NET
совершенно по-другому.
Рис. 1. В Visual Basic 6.0 имеется add-in, упрощающий разработку
элемента управления с помощью автоматического добавления и отображения
свойств элемента управления.
При создании собственного элемента управления наследование позволяет
избежать дублирования путем его построения на основе функциональных
возможностей любого другого элемента управления .NET. Чтобы создать
собственный элемент управления TextBox, создайте элемент управления,
который наследуется из существующего элемента управления TextBox, а не
из UserControl. Базовый элемент управления, т.е. источник наследования,
предоставляет все свои функциональные возможности. Следовательно,
разработчику необходимо закодировать только те аспекты элемента
управления, которые отличаются от этой основы. В качестве практики ниже
приводится код, необходимый для создания собственного элемента
управления TextBox, позволяющего ввод только числовых данных.
Примечание Чтобы
самостоятельно проверить этот код, просто создайте новый проект Visual
Basic .NET с помощью шаблона Windows Application так, чтобы получить
пустую форму для проверки нового элемента управления, и затем добавьте к
проекту новый класс (NumericTextBox). Замените код в новом файле класса
на приведенный ниже код и затем постройте свой проект. После этого
проект можно добавить на панель инструментов. В меню Tools щелкните
Customize Toolbox и укажите путь к .exe-файлу, созданному в результате
построения проекта:
Public Class NumericTextBox
Inherits System.Windows.Forms.TextBox
Protected Overrides Sub OnKeyPress(ByVal e As _
System.Windows.Forms.KeyPressEventArgs)
If Not Char.IsDigit(e.KeyChar) Then
e.Handled = True
Else
e.Handled = False
End If
End Sub
End Class
Выше был приведен действительно весь требуемый код, однако, если быть
придирчивым, количество строк кода можно сократить с помощью булевой
логики:
Public Class NumericTextBox
Inherits System.Windows.Forms.TextBox
Protected Overrides Sub OnKeyPress(ByVal e As _
System.Windows.Forms.KeyPressEventArgs)
e.Handled = Not Char.IsDigit(e.KeyChar)
End Sub
End Class
Не выполняя других функций, этот элемент управления правильно
выводится на экран и располагает теми же событиями, свойствами и
методами, как и TextBox. Кроме того, с этим элементом управления можно
связать данные без дополнительного кода, поскольку эти функциональные
возможности также предоставляются в базовом элементе управления.
Примечание Этот элемент
управления довольно ограничен и позволяет вводить только цифры 0-9.
Другим словами, ввод числовых данных с запятыми, десятичными точками или
отрицательным знаком недопустим. Более функциональный метод проверки
достоверности ввода будет рассмотрен в первой статье этой серии.
(Дополнительная информация об этих четырех примерах содержится в разделе
Примеры далее в этой статье).
Аналогичный элемент управления, построенный с помощью Visual Basic
6.0, имел бы почти такой же объем значимого кода, но также и большой
объем сервисного кода, служащего для обработки изменения размеров
элемента управления и предоставления выборочных свойств. Хотя сокращение
объема кода, который нужно написать, - это большое преимущество
построения элементов управления с помощью наследования, но это только
одно преимущество. Более значительное преимущество наследования состоит
в том, что недавно созданный элемент управления будет работать с любым
кодом, ожидавшим тип базового элемента управления, который позволяет
передавать новый NumericTextBox в любую процедуру, ожидающую элемент
управления TextBox. Расширение существующего элемента управления вместо
работы с классом UserControl позволяет не только использовать
функциональные возможности базового элемента управления, но также
получить дополнительное преимущество, связанное со знакомством
разработчиков со свойствами, методами и событиями базового элемента
управления. Если разработчик знает, как работать со стандартным TextBox,
он может работать с новым NumericTextBox без дополнительного обучения.
Возможность наследования из существующего класса (в данном случае из
элемента управления) является одним из самых значительных различий между
Visual Basic 6.0 и .NET, но не единственным. Если изучить примеры,
приведенные далее в этом ряде статей, можно заметить, что элементы
управления Windows Forms обладают многими мощными возможностями, и на их
создание будет затрачено меньше усилий по сравнению с более ранними
версиями Visual Basic.
Ресурсы
Чтобы облегчить построение собственных элементов управления Windows
Forms, ниже приводится список ресурсов, посвященных некоторым из
наиболее общих концепций, методов и проблем.
-
Наследование из базового класса в Microsoft .NET
-
Создание элементов управления для Windows Forms (Документация по
Visual Studio .NET)
-
Разработка элементов управления Windows Forms (Документация по
.NET Framework)
-
Разработка в .NET Framework принудительных пользовательских
элементов управления, предназначенных для Forms (MSDN Magazine,
апрель 2002 г.)
-
Примеры .NET для Windows Forms: создание элементов управления
(из .NET QuickStarts)
-
Отладка элементов управления Windows Forms, созданных с помощью
Visual Basic .NET или Visual C# .NET
В дополнение к вышеупомянутым ресурсам были составлены несколько
примеров, иллюстрирующих некоторые из наиболее общих концепций
разработки элементов управления. Здесь приводится классификация
элементов управления по небольшим группам категорий, основанная на
требующихся функциональных возможностях:
- Незначительно расширенные элементы управления
Внесение небольших изменений в поведение существующего элемента
управления, например, NumericTextBox, (см. выше) и Regular
Expression TextBox, который подробно рассматривается далее в разделе
Примеры, и добавление лишь немногих свойств, методов или событий,
если таковые вообще имеются. Элементы управления в этой категории
обычно наследуются из существующего элемента управления (например,
System.Windows.Forms.TextBox).
- Существенно расширенные элементы управления
Построение на основе существующего элемента управления и добавление
многих новых функциональных возможностей и, как правило, нескольких
новых свойств, методов и/или событий. Примерами этой категории
элементов управления являются связанный с данными помеченный ListBox
и связанный с данными группированный TreeView (подробнее см. далее в
разделе Примеры). Как и незначительно расширенные элементы
управления, элементы управления в этой категории обычно наследуются
из существующего элемента управления (например,
System.Windows.Forms.TreeView).
- Составные элементы управления
Это элементы управления, которые объединяют несколько других
элементов управления, например, TextBox со связанным элементом
управления up/down, и подразумевают добавление пользовательских
свойств, методов и событий. Примером этого типа элементов управления
является связанная с данными радио-кнопка опроса (подробно
рассматриваемая далее в разделе Примеры). Элементы управления этой
категории должны наследоваться из System.Windows.Forms.UserControl.
Для быстрого начала работы над ними необходимо изучить шаблон
UserControl в Visual Studio .NET.
- Полностью пользовательские элементы управления
Это элементы управления, которые разрабатываются "с нуля", или любые
элементы управления, прорисовка которых обрабатывается собственными
силами. Одним из примеров этого типа пользовательского элемента
управления является связанный с данными элемент управления
просмотром эскизов (подробно рассматриваемый далее в разделе
Примеры), однако к этой категории можно отнести широкий спектр
элементов управления. Элементы управления в этой категории просто
наследуются из System.Windows.Form.Control.
- Расширители функциональности (Extender Providers)
Этот тип элементов управления или компонентов в значительной степени
отличается от других четырех категорий, поскольку он работает путем
добавления функциональных возможностей к другим элементам управления
в той же форме. Примерами этого типа элементов управления являются
ToolTip, ErrorProvider и HelpProvider. Процесс построения одного из
таких элементов управления рассматривается в
первой статье этой серии.
Примеры
Каждый из этих примеров иллюстрирует определенные аспекты разработки
элемента управления, включая наследование, связывание данных и рисование
собственной графики. Все примеры можно загрузить в одном файле по ссылке
в начале этой статьи.
В первой статье "Добавление
проверки правильности регулярного выражения" рассматриваются основы
наследования из другого элемента управления и добавление собственных
свойств, методов и событий наряду с добавлением собственного кода. Кроме
того, этот пример иллюстрирует альтернативный способ добавления тех же
функциональных возможностей через расширитель функциональности. Во
второй статье "Объединение
нескольких элементов управления в один" с помощью элемента
управления - радио-кнопки опроса - иллюстрируется процесс создания
пользовательского элемента управления путем объединения существующих
элементов управления и описывается, как простое связывание данных
работает с разрабатываемыми элементами управления.
В оставшихся примерах показана более продвинутая разработка элементов
управления, включающая сложное связывание данных и рисование
собственного пользовательского интерфейса с помощью GDI+. В третьей
статье "Расширение
элемента управления TreeView" описывается разработка относительно
сложного связанного с данными элемента управления TreeView, выводящего
на экран иерархию элементов на основе источника данных. В последней
статье "Рисование
собственных элементов управления с помощью GDI+" подробно
рассматривается элемент управления, обрабатывающий всю прорисовку:
связанный с данными просмотр эскизов. Помимо специфичных для элемента
управления функциональных возможностей последний пример иллюстрирует
также основные методы GDI+, такие как рисование строк, прямоугольников и
изображений.
Резюме
Пользовательская разработка элемента управления в любых целях,
например, для личного использования, групповой разработки или
коммерческой продажи, является одной из самых мощных форм компонентной
технологии. Концепция упаковки внешнего вида и функциональных
возможностей в свободно распространяемый пакет стала главным фактором
успеха визуальных средств разработки, таких как Visual Basic, и
продолжает оставаться популярной концепцией в текущих версиях этих
средств. Разработка элементов управления претерпела в .NET большие
изменения к лучшему, поскольку новые возможности, в частности,
наследование, упрощают процесс настройки существующих элементов
управления при одновременном уменьшении объема требуемого кода.
Вышеописанные примеры спроектированы так, чтобы ввести разработчика в
создание пользовательских элементов управления, проиллюстрировать
некоторые важные методы разработки элементов управления и возможно даже
дать некоторые идеи для создания собственных элементов управления.