Опубликован: 13.07.2010 | Доступ: свободный | Студентов: 890 / 20 | Оценка: 4.40 / 4.20 | Длительность: 77:34:00
Самостоятельная работа 36:

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

Атрибуты как средство дополнительной настройки компонента

Атрибут, это дополнительный механизм уточнения поведения класса или его члена, относящийся к современным технологиям программирования. Атрибуты - это типы, порожденные абстрактным классом Attribute. Имена всех библиотечных атрибутов заканчиваются словом Attribute, но для простоты язык C# позволяет сокращать запись и указывать название атрибута без этого постфикса (postfix).

Атрибут прикрепляется к объекту с помощью описания конструктора в квадратных скобках, но для атрибутов уровня сборки или модуля прикрепление выполняется с помощью ключевых слов Assembly и Module соответственно.

К объекту могут прикрепляться несколько атрибутов в индивидуальных квадратных скобках или списком в общих квадратных скобках. Например, инструкция прикрепления нескольких атрибутов к классу вот такая

// Всплывающая подсказка компонента в панели Toolbox
    [Description("Текстовая метка с градиентной заливкой фона")]
    // Подключение пиктограммы компонента для панели Toolbox 
    [ToolboxBitmap(typeof(GradientLabel))]
    // Подключение класса дизайнера к классу компонента       
    [Designer(typeof(GradientLabelDesigner))]
    
    partial class GradientLabel
    {
        .........................................
    }

равносильна такой инструкции

// Всплывающая подсказка компонента в панели Toolbox
    [Description("Текстовая метка с градиентной заливкой фона"),
    // Подключение пиктограммы компонента для панели Toolbox 
    ToolboxBitmap(typeof(GradientLabel)),
    // Подключение класса дизайнера к классу компонента       
    Designer(typeof(GradientLabelDesigner))]
    
    partial class GradientLabel
    {
        .........................................
    }

Конструктор атрибута может принимать два вида параметров:

  1. Позиционные параметры - параметры, указанные в конструкторе класса-атрибута и обязательные к упоминанию их первыми в строгом порядке следования
  2. Именованные параметры - поля и свойства класса-атрибута, которые представляют собой пары 'имя=значение' и которые можно указывать по желанию (можно и не указывать) после позиционных параметров без соблюдения порядка следования. Именованные параметры внутри класса-атрибута должны быть объявлены доступными как для чтения, так и для записи. Параметры, доступные только для чтения, не могут использоваться как именованные.

Различают следующие атрибуты:

  1. Атрибуты, используемые компилятором
  2. Атрибуты, используемые средой проектирования
  3. Атрибуты, используемые библиотекой классов
  4. Пользовательские атрибуты

В таблице приведены некоторые атрибуты, используемые самой средой проектирования. Они нам понадобятся для настройки поведения компонента в режиме проектирования.

Атрибуты настроек компонента в режиме проектирования
Класс атрибута Конструкторы атрибута Примеры прикрепления Пояснения

System.ComponentModel. DefaultPropertyAttribute

public DefaultPropertyAttribute(string name)

[DefaultProperty("Text")]

Указывает свойство по умолчанию. Это свойство будет активно в панели Properties при первом редактировании экземпляра компонента. Обычно таким атрибутом помечают часто изменяемые свойства компонента, например, для Label, TextBox, Button - это свойство Text. Прикрепляется к классу

System.ComponentModel. DefaultEventAttribute

public DefaultEventAttribute(string name)

[DefaultEvent("Click")]

Указывает событие по умолчанию, для которого будет создан обработчик при двойном щелчке пользователя на экземпляре компонента, помещенного на форму в режиме View Designer. Прикрепляется к классу

System.ComponentModel. DefaultValueAttribute

public DefaultValueAttribute(bool value)
      public DefaultValueAttribute(byte value)
      public DefaultValueAttribute(char value)
      public DefaultValueAttribute(double value)      
      public DefaultValueAttribute(float value)
      public DefaultValueAttribute(int value)
      public DefaultValueAttribute(long value)
      public DefaultValueAttribute(object value)
      public DefaultValueAttribute(short value)
      public DefaultValueAttribute(string value)
      public DefaultValueAttribute(System.Type type, string value)

[DefaultValue(10)]

[DefaultValue(typeof(Color), "Red")]

Указывает значение свойства по умолчанию. При наличии такого атрибута, прикрепленного к свойству, редактор свойств Properties отображает значение стилем Regular, а без атрибута - стилем Bold и оболочка генерирует код явного присвоения значения данному свойству в файле Designer.cs формы. Конструктор с одним параметром используется для свойств элементарных типов, а конструктор с двумя параметрами - для статических свойств класса. При наличии этого атрибута активизируется команда Reset контекстного меню редактора значения свойства, с помощью которой свойству можно вернуть значение по умолчанию. Прикрепляется к свойству

System.ComponentModel. CategoryAttribute

public CategoryAttribute()
    public CategoryAttribute(string category)

[Category("Gradient")]

Создает категорию в панели свойств и помещает в нее прикрепленное свойство. Прикрепляется к свойству

System.ComponentModel. DescriptionAttribute

public DescriptionAttribute()
    public DescriptionAttribute(string description)

[Description("Цвет начала заливки")]

Описание выделенного свойства или события, которое появится в нижней части панели свойств. Прикрепляется к свойству или событию при их описании в теле класса

System.ComponentModel. BrowsableAttribute

public BrowsableAttribute(bool browsable)

[Browsable(false)]

Отключает с аргументом false появление свойства или события в панели Properties. По умолчанию все публичные свойства и события класса компонента показываются в редакторе свойств. Прикрепляется к свойству или событию при их описании в теле класса

System.ComponentModel. DisplayNameAttribute

public DisplayNameAttribute()
    public DisplayNameAttribute(string displayName)

[DisplayName("End Color")]

[DisplayName("Цвет завершения заливки")]

 

Задает представление, как имя свойства будет отображаться в панели свойств. Иногда может понадобиться разделить пробелами составное имя свойства или события при их представлении в панели Properties, или отобразить на русском языке, или по-турецки

System.ComponentModel. PasswordPropertyTextAttribute

public PasswordPropertyTextAttribute()
    public PasswordPropertyTextAttribute(bool password)

[PasswordPropertyText(true)]

Устанавливает режим отображения значения свойства в панели Properties звездочками

System.ComponentModel. ReadOnlyAttribute

public ReadOnlyAttribute(bool isReadOnly)

[ReadOnly(true)]

true - свойство нельзя редактировать в панели Properties (в режиме проектирования) и оно представляется серым цветом. Для статических свойств такой механизм установлен по умолчанию

System.ComponentModel. MergablePropertyAttribute

public MergablePropertyAttribute(bool allowMerge)

[MergableProperty(false)]

При групповом выделении разнотипных компонентов, имеющих одинаковое имя свойства, запрещает для помеченного этим атрибутом свойства изменение "за компанию". По умолчанию true - разрешено групповое изменение значения любого общедоступного свойства

System.ComponentModel. ParenthesizePropertyNameAttribute

public ParenthesizePropertyNameAttribute()
    public ParenthesizePropertyNameAttribute(bool needParenthesis)

[ParenthesizePropertyName(true)]

С параметром true указывает редактору свойств отображать имя свойства в круглых скобках

System.ComponentModel. AttributeProviderAttribute

public AttributeProviderAttribute(string typeName)
      public AttributeProviderAttribute(string typeName, string
    propertyName)
    public AttributeProviderAttribute(System.Type type)

[AttributeProvider(typeof(Button))]

Присоединяет к прикрепленному типу атрибуты из другого типа

System.ComponentModel.ToolboxItemAttribute

public ToolboxItemAttribute(bool defaultType)
    public ToolboxItemAttribute(string toolboxItemTypeName)
    public ToolboxItemAttribute(System.Type toolboxItemType)

[ToolboxItem(true)]

Значение true по умолчанию обязывает компонент появляться в панели Toolbox оболочки. Прикрепляется к классу

System.Drawing.ToolboxBitmapAttribute

public ToolboxBitmapAttribute(string imageFile)
    public ToolboxBitmapAttribute(System.Type t)
    public ToolboxBitmapAttribute(System.Type t, string name)

[ToolboxBitmap(typeof(GradientLabel), "GradientLabel.bmp")]

Загрузка пиктограммы компонента размером 16x16 px в формате BMP или ICO. Прикрепляется к классу

System.ComponentModel.DesignTimeVisibleAttribute

public DesignTimeVisibleAttribute()
    public DesignTimeVisibleAttribute(bool visible)

[DesignTimeVisible(false)]

Аргумент false указывает оболочке, что компонент не должен быть виден в режиме разработки

Воспользуемся некоторыми из приведенных атрибутов для частичной настройки нашего компонента GradientLabel. Вспомним, что атрибуты прикрепляются перед объектом влияния по-отдельности в квадратных скобках каждый, либо списком в общих квадратных скобках.

  • Дополните вторую часть класса компонента в файле GradientLabel.cs атрибутами, выделенными в следующем листинге
/////////////////////////////////////////////////////////////////
// Блок кода №2 продолжения класса GradientLabel 
/////////////////////////////////////////////////////////////////
namespace MyControl
{
    // Всплывающая подсказка компонента в панели Toolbox
    [Description("Текстовая метка с градиентной заливкой фона")]
    // Подключение пиктограммы компонента для панели Toolbox 
    [ToolboxBitmap(typeof(GradientLabel))]
    
    partial class GradientLabel
    {
        // Закрытые поля
        private Color startColor = Color.Yellow;
        private Color endColor = Color.Red;
    
        // Категория свойства в панели Properties
        [Category("Gradient")]
        // Пояснение для выделенного свойства 
        // в нижней части панели Properties
        [Description("Цвет начала заливки")]
        // Значение свойства по умолчанию 
        [DefaultValue(typeof(Color), "Yellow")] 
        // Представление имени свойства в панели Properties
        // [DisplayName("Начало заливки")]
    
        public Color StartColor // Общедоступное свойство 
        {
            get { return startColor; }
            set
            {
                // Меняем значение
                startColor = value;
    
                // Инициируем событие
                OnGradientChange(EventArgs.Empty);
            }
        }
    
        // Альтернативный синтаксис прикрепления атрибутов 
        [Category("Gradient"), Description("Цвет завершения заливки"), 
        DefaultValue(typeof(Color), "Red")]
        // [DisplayName("End Color")]
    
        public Color EndColor // Общедоступное свойство 
        {
            get { return endColor; }
            set 
            { 
                // Меняем значение
                endColor = value;
    
                // Инициируем событие
                OnGradientChange(EventArgs.Empty);
            }
        }
    
        // Пояснение для выделенного события 
        // в нижней части панели Properties 
        [Description("Событие изменения цвета\n"
            + "границ градиентной заливки")] 
    
        // Объявление события изменения свойств цвета градиента 
        public event EventHandler GradientChange; 
    
        // Функция диспетчеризации события GradientChange
        protected virtual void OnGradientChange(EventArgs args)
        {
            // Перерисовываем компонент 
            this.Invalidate();
    
            // Если есть зарегистрированные обработчики,
            // то инициируем событие и вызываем обработчики 
            if (GradientChange != null)
                GradientChange(this, args);
        }
    
        // Переопределение метода OnPaint()
        protected override void OnPaint(PaintEventArgs e)
        {
            // Контекст графического устройства
            Graphics gr = e.Graphics;
    
            // Создаем кисть и заливаем фон текстового блока 
            float angle = 10.0F;
            Brush brush = new LinearGradientBrush(
                this.ClientRectangle, startColor, endColor, angle);
            gr.FillRectangle(brush, this.ClientRectangle);
    
            // Сразу освобождаем кисть как ограниченный ресурс 
            brush.Dispose();
    
            // Вызываем после заливки, иначе закрашивается текст
            base.OnPaint(e);
        }
    }
}
Листинг 36.6. Добавление атрибутов в класс GradientLabel