Интерфейс времени проектирования для компонента
Добавление к компоненту смарт-тега
Смарт-теги (smart tags - интеллектуальные дескрипторы) обеспечивают индивидуальные средства настройки компонентов, позволяющие вынести в специальный диалог наиболее важные свойства и методы. Смарт-теги встречаются во многих высокоразвитых библиотечных компонентах и раскрываются щелчком на треугольничке в правой верхней части представления компонента на форме в режиме проектирования. Например, для библиотечного компонента ComboBox это представление смарт-тега будет таким
Смарт-теги создаются на базе библиотечного класса
System.ComponentModel.Design.DesignerActionList
Для создания смарт-тега компонента вначале нужно создать класс со списком свойств и методов, которые планируется вынести в смарт-тег для быстрого редактирования. Этот класс списка выносимых для редактирования элементов компонента должен быть создан как расширение библиотечного класса DesignerActionList. Он должен содержать ссылки на включаемые в смарт-тег свойства и методы самого компонента, полученные с применением теории отражения из экземпляра класса (объекта) компонента. Затем в привязываемом к компоненту классе-дизайнере, наследнике библиотечного класса ControlDesigner, нужно переопределить унаследованное виртуальное свойство ActionLists, чтобы включить список редактируемых элементов в смарт-тег.
Создадим смарт-тег для нашего разрабатываемого компонента GradientLabel.
- Добавьте в конец файла GradientLabelDesigner.cs следующий блок кода №3, определяющий список свойств и методов, помещаемых в смарт-тег
//*/////////////////////////////////////////////////////////////// // Блок кода №3. Создание списка выносимых в смарт-тег элементов компонента ////////////////////////////////////////////////////////////////// namespace MyControl { // Пусть класс доступен коду только внутри сборки компонента internal partial class GradientLabelActionList : DesignerActionList { // Объявили ссылку на объект компонента GradientLabel gradientLabel; // Конструктор public GradientLabelActionList(IComponent component) : base(component) { // Привели и сохранили ссылку на редактируемый компонент gradientLabel = (GradientLabel)component; } // Вспомогательная функция реализации отражения private PropertyDescriptor GetPropertyByName(String propName) { PropertyDescriptor prop = TypeDescriptor.GetProperties(gradientLabel)[propName]; if (prop == null) throw new ArgumentException("Свойство не существует", propName); return prop; } // Элементы компонента, выносимые в диалог смарт-тега public Color StartColor { get { return this.gradientLabel.StartColor; } set { this.GetPropertyByName("StartColor").SetValue(gradientLabel, value); } } public Color EndColor { get { return this.gradientLabel.EndColor; } set { this.GetPropertyByName("EndColor").SetValue(gradientLabel, value); } } public void InvertColors() { Color tmp = gradientLabel.StartColor; this.StartColor = gradientLabel.EndColor; this.EndColor = tmp; } } } //***************************************************************/Листинг 36.9. Класс списка добавляемых в смарт-тег элементов компонента
- Добавьте в конец файла GradientLabelDesigner.cs следующий блок кода №4, определяющий смарт-тег со списком выносимых в диалог свойств и методов
//*/////////////////////////////////////////////////////////////// // Блок кода №4. Создание смарт-тега с заданным списком элементов ////////////////////////////////////////////////////////////////// namespace MyControl { partial class GradientLabelDesigner { // Базовое поле DesignerActionListCollection actionLists; // Переопределение виртуального свойства ActionLists, унаследованного // классом System.Windows.Forms.Design.ControlDesigner от // класса System.ComponentModel.Design.ComponentDesigner public override DesignerActionListCollection ActionLists { get { // Если еще не создавали смарт-тег actionLists if (actionLists == null) { // Создали окно смарт-тега actionLists = new DesignerActionListCollection(); // Создали список элементов окна GradientLabelActionList gradientLabelActionList = new GradientLabelActionList(this.Component); // Добавили список элементов в коллекцию окна actionLists.Add(gradientLabelActionList); } return actionLists; } } } } //***************************************************************/Листинг 36.10. Класс смарт-тега со списком редактируемых элементов компонента
- Откомпилируйте проект компонента и убедитесь, что у компонента появился смарт-тег с указанными элементами
Обратите внимание на то, что код интерфейсной части компонента работает в режиме проектирования и нам не нужно запускать приложение с компонентом на выполнение. Оболочка сама выполняет необходимые действия на этапе проектирования в соответствии с заложенной нами логикой поведения компонента на этом этапе.