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

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

Исключение свойств и событий из панели Properties

При конструировании компонентов на основе наследования других классов некоторые свойства и события в расширяемом классе возможно потребуется скрыть. Так например, в нашем примере градиентной заливки фона унаследованное свойство BackColor становится излишним. Мы не можем его скрыть с помощью атрибута Browsable(false), поскольку оно в текущем слое расширения не объявляется, а наследуется из библиотечного класса System.Windows.Forms.Control через класс Label. Здесь нужно применить специальную технику, основанную на расширении класса дизайнера System.Windows.Forms.Design.ControlDesigner.

В классе-расширении для сокрытия свойств и событий нужно переопределить методы

protected virtual void PreFilterProperties(System.Collections.IDictionary properties)
    protected virtual void PreFilterEvents(System.Collections.IDictionary events)

Этим методам передаются коллекции properties и events всех свойств и методов, отображаемых дизайнером в панели Properties.

Для отключения показа свойства или метода в панели Properties достаточно внутри соответствующего метода-фильтра выполнить одну из инструкций

properties.Remove("BackColor");
    events.Remove("DoubleClick");
  • Добавьте в конец файла GradientLabelDesigner.cs следующий блок кода №8, скрывающий свойство BackColor и событие DoubleClick из панели Properties оболочки
//*///////////////////////////////////////////////////////////////
// Блок кода №8. Сокрытие свойств и событий из панели Properties
//////////////////////////////////////////////////////////////////
namespace MyControl
{
    partial class GradientLabelDesigner
    {
        protected override void PreFilterProperties(System.Collections.IDictionary properties)
        {
            base.PreFilterProperties(properties);
    
            // Скрываем в панели Properties свойство BackColor
            properties.Remove("BackColor");
        }
    
        protected override void PreFilterEvents(System.Collections.IDictionary events)
        {
            base.PreFilterEvents(events);
    
            // Скрываем в панели Properties событие DoubleClick
            events.Remove("DoubleClick");
        }
    }
}
//***************************************************************/
Листинг 36.17. Код сокрытия свойства и события из панели Properties
  • Откомпилируйте решение и убедитесь в работоспособности кода, который скрывает как свойство BackColor, так и событие DoubleClick компонента GradientLabel

Свойства режима проектирования

Некоторые свойства нужны и существуют только на этапе проектирования. Например, свойства категории Design в панели свойств: GenerateMember, Locked, Modifiers - реально отсутствуют у экземпляра нашего компонента, но в то же время на этапе разработки оболочка их создает и поддерживает.


Для того, чтобы добавить свойство для режима разработки, нужно добавить его в коллекцию properties в перегрузке метода PreFilterProperties() класса ControlDesigner. Очень важно проследить, чтобы добавляемое свойство режима разработки объявлялось с атрибутом

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

Этот атрибут не дает такому свойству класса компонента попасть в режим выполнения.

  • Дополните блок кода №8 в файле GradientLabelDesigner.cs следующими строками
//*///////////////////////////////////////////////////////////////
// Блок кода №8. Сокрытие свойств и событий из панели Properties
// Добавление свойств режима разработки в панель Properties
//////////////////////////////////////////////////////////////////
namespace MyControl
{
    partial class GradientLabelDesigner
    {
        // Создание свойства в классе компонента
        int designProp; // Базовое поле
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Category("Design")]
        [Description("Свойство режима проектирования")]
        public int DesignProp
        {
            get { return designProp; }
            set { designProp = value; }
        }
    
        protected override void PreFilterProperties(System.Collections.IDictionary properties)
        {
            base.PreFilterProperties(properties);
    
            // Скрываем в панели Properties свойство BackColor
            properties.Remove("BackColor");
    
            ////////////////////////////////////////////////////////////////
            // Добавление свойства этапа проектирования в панель Properties:
            ////////////////////////////////////////////////////////////////
            // Извлекаем существующее свойство из класса компонента
            PropertyDescriptor oldPropDescr = TypeDescriptor.GetProperties(this)["DesignProp"];
            // Объявляем массив для атрибутов нужной размерности
            Attribute[] attributes = new Attribute[oldPropDescr.Attributes.Count];
            // Копируем атрибуты свойства в массив
            oldPropDescr.Attributes.CopyTo(attributes, 0);
            // Создаем дополнительное свойство для панели Properties
            PropertyDescriptor propDescr = 
                TypeDescriptor.CreateProperty(this.GetType(), oldPropDescr, attributes);
            // Добавляем дополнительное свойство в панель Properties
            properties["DesignProp"] = propDescr;
        }
    
        protected override void PreFilterEvents(System.Collections.IDictionary events)
        {
            base.PreFilterEvents(events);
    
            // Скрываем в панели Properties событие DoubleClick
            events.Remove("DoubleClick");
        }
    }
}
//***************************************************************/
Листинг 36.18. Дополнительное свойство только для режима проектирования
  • Откомпилируйте компонент и убедитесь, что свойство DesignProp класса GradientLabelDesigner появилось в категории Design панели Properties, хотя в самом классе компонента GradientLabel такого свойства нет