Интерфейс времени проектирования для компонента
Усовершенствование смарт-тега компонента
К созданному смарт-тегу можно сделать несколько замечаний
- По обновлению окна диалога:
- По оформлению окна диалога:
- подписи элементов смарт-тега совпадают с именами свойств и методов, что не всегда может быть приемлемо для пользователя компонента. Было бы лучше написать их раздельно или вообще перевести на русский язык
- порядком следования элементов в диалоговом окне смарт-тега формируется по алфавиту, а этим процессом желательно бы управлять
Устранение замечания по обновлению окна диалога
Для обновления диалогового окна смарт-тега при изменении цветов компонента нужно в конструкторе класса GradientLabelActionList формирования списка элементов сохранить ссылку на сервис System.ComponentModel.Design.DesignerActionUIService. Затем в нашем методе InvertColors() или в аксессорах set{ } свойств StartColor и EndColor вызвать метод Refresh() этого сервиса.
- Дополните класс GradientLabelActionList компонента следующим кодом
//*/////////////////////////////////////////////////////////////// // Блок кода №3. Создание списка выносимых в смарт-тег элементов компонента ////////////////////////////////////////////////////////////////// namespace MyControl { // Пусть класс доступен коду только внутри сборки компонента internal partial class GradientLabelActionList : DesignerActionList { // Объявили ссылку на объект компонента GradientLabel gradientLabel; // Объявили ссылку на сервис смарт-тега DesignerActionUIService designerActionUIService; // Конструктор public GradientLabelActionList(IComponent component) : base(component) { // Привели и сохранили ссылку на редактируемый компонент gradientLabel = (GradientLabel)component; // Привели и сохранили ссылку на сервис смарт-тега designerActionUIService = (DesignerActionUIService) this.GetService(typeof(DesignerActionUIService)); } // Вспомогательная функция реализации отражения 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); // Обновляем диалоговое окно смарт-тега designerActionUIService.Refresh(gradientLabel); } } public Color EndColor { get { return this.gradientLabel.EndColor; } set { this.GetPropertyByName("EndColor").SetValue(gradientLabel, value); // Обновляем диалоговое окно смарт-тега designerActionUIService.Refresh(gradientLabel); } } public void InvertColors() { Color tmp = gradientLabel.StartColor; this.StartColor = gradientLabel.EndColor; this.EndColor = tmp; } } } //***************************************************************/Листинг 36.11. Код класса GradientLabelActionList для обновления окна смарт-тега
Устранение замечания по оформлению окна диалога
Для того, чтобы изменить порядок следования элементов смарт-тега и сделать окно диалога более информативным, нужно изменить коллекцию элементов окна, представленную классом System.ComponentModel.Design.DesignerActionItemCollection. Для этого в классе формирования списка элементов окна GradientLabelActionList нужно переопределить унаследованный библиотечный метод DesignerActionList.GetSortedActionItems() и в нем вручную формировать коллекцию окна смарт-тега с нужным порядком элементов.
Каждый элемент коллекции окна смарт-тега представлен одним из классов:
- System.ComponentModel.Design.DesignerActionHeaderItem - устанавливает заголовок группы элементов окна смарт-тега
- System.ComponentModel.Design.DesignerActionTextItem - выводит надписи к элементам смарт-тега
- System.ComponentModel.Design.DesignerActionPropertyItem - представляет свойство и в зависимости от типа свойства виден как текстовое поле, выпадающий список или флажок
- System.ComponentModel.Design.DesignerActionMethodItem - представляет ссылку для вызова метода
Используем перечисленные классы представления элементов окна и сформируем коллекцию в переопределении виртуального метода GetSortedActionItems(). При этом создадим в смарт-теге три группы элементов:
- Группу свойств
- Группу методов
- Группу для отображения дополнительной информации
- Добавьте в файл GradientLabelDesigner.cs блок кода №5, переопределяющий виртуальный метод DesignerActionList.GetSortedActionItems() базового класса
//*/////////////////////////////////////////////////////////////// // Блок кода №5. Ручное формирование списка элементов в классе GradientLabelActionList ////////////////////////////////////////////////////////////////// namespace MyControl { partial class GradientLabelActionList { // Переопределяем виртуальный метод базового класса DesignerActionList public override DesignerActionItemCollection GetSortedActionItems() { // Создаем объект коллекции элементов смарт-тега DesignerActionItemCollection items = new DesignerActionItemCollection(); // Формируем категорию "Свойства" (Properties) // Заголовок категории items.Add(new DesignerActionHeaderItem("Свойства", "Properties")); // Элементы категории items.Add(new DesignerActionPropertyItem("StartColor", "Начальный цвет", "Properties", "Цвет начала градиентной заливки")); items.Add(new DesignerActionPropertyItem("EndColor", "Конечный цвет", "Properties", "Цвет завершения градиентной заливки")); // Формируем категорию "Методы" (Methods), если цвета не равны! if (StartColor != EndColor) { // Заголовок категории items.Add(new DesignerActionHeaderItem("Методы", "Methods")); // Ссылка вызова метода с одновременным созданием опции в контекстном меню items.Add(new DesignerActionMethodItem(this, "InvertColors", "Перевернуть цвета", "Methods", "Поменять начальный и конечный цвета местами", true)); } // Формируем категорию "Информация" (Info) // Заголовок категории items.Add(new DesignerActionHeaderItem("Информация", "Info")); // Текстовый элемент категории string info = String.Format("Размер компонента {0}x{1}", gradientLabel.Width, gradientLabel.Height); items.Add(new DesignerActionTextItem(info, "Info")); return items; } } } //***************************************************************/Листинг 36.12. Дополнение в классе GradientLabelActionList кода формирования списка
- Откомпилируйте проект компонента командой Build/Build Solution и убедитесь, что окно диалога компонента в режиме проектирования приобрело профессиональный вид