Опубликован: 13.07.2010 | Уровень: специалист | Доступ: платный
Самостоятельная работа 36:

Интерфейс времени проектирования для компонента

Добавление к компоненту смарт-тега

Смарт-теги (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. Класс смарт-тега со списком редактируемых элементов компонента
  • Откомпилируйте проект компонента и убедитесь, что у компонента появился смарт-тег с указанными элементами


Обратите внимание на то, что код интерфейсной части компонента работает в режиме проектирования и нам не нужно запускать приложение с компонентом на выполнение. Оболочка сама выполняет необходимые действия на этапе проектирования в соответствии с заложенной нами логикой поведения компонента на этом этапе.

Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000