Интерфейс времени проектирования для компонента
Усовершенствование смарт-тега компонента
К созданному смарт-тегу можно сделать несколько замечаний
- По обновлению окна диалога:
- По оформлению окна диалога:
- подписи элементов смарт-тега совпадают с именами свойств и методов, что не всегда может быть приемлемо для пользователя компонента. Было бы лучше написать их раздельно или вообще перевести на русский язык
- порядком следования элементов в диалоговом окне смарт-тега формируется по алфавиту, а этим процессом желательно бы управлять
Устранение замечания по обновлению окна диалога
Для обновления диалогового окна смарт-тега при изменении цветов компонента нужно в конструкторе класса 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 и
убедитесь, что окно диалога компонента в режиме проектирования
приобрело профессиональный вид
