Поделиться через


Атрибуты и поддержка во время разработки

Расширения, предназначенные для поддержки во время разработки, обычно реализуются в коде, существующем отдельно от кода компонентов. Для связи поставщиков средств поддержки во время разработки с типами или отдельными членами типов используются разнообразные атрибуты.

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

Атрибут DesignerAttribute связывает конструктор с типом. Атрибут TypeConverterAttribute связывает преобразователь типов с типом или членом типа. Атрибут EditorAttribute связывает редактор типов пользовательского интерфейса с типом или членом типа.

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

Значение, которое будет присваиваться свойству по умолчанию при загрузке компонента во время разработки, можно задать, указав для свойства атрибут DefaultValueAttribute. Атрибут DefaultValueAttribute переопределяет значение, устанавливаемое во время разработки кодом инициализации компонента, однако данный атрибут не переопределяет значение, устанавливаемое конструктором.

Атрибуты для настройки функционирования окна свойств

Чтобы указать, будет ли свойство или событие отображаться в окне Свойства, следует задать для него атрибут BrowsableAttribute. Изменить набор свойств и событий, предоставляемых окну Свойства во время разработки, можно также и с помощью конструктора, реализующего интерфейс IDesignerFilter. Чтобы задать категорию, под которой свойство или событие будет включено в окно Свойства, следует указать для данного свойства или события атрибут CategoryAttribute. Чтобы задать описание, которое будет отображаться для свойства или события в окне Свойства, нужно указать для данного свойства или события атрибут DescriptionAttribute.

Чтобы указать, что свойство может быть установлено лишь во время разработки, следует задать для него атрибут DesignOnlyAttribute. Чтобы указать, что свойство предназначено только для чтения или что его можно считывать и записывать только во время разработки, следует задать для него атрибут ReadOnlyAttribute.

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

Чтобы указать, что свойство, имеющее вложенные или дочерние свойства, должно получать уведомление об изменении вложенного свойства, следует задать для вложенного свойства, которое должно посылать указанное уведомление, атрибут NotifyParentPropertyAttribute.

Чтобы указать, следует ли обновлять свойства компонента, или указать на необходимость обновления представления конструктора, следует задать атрибут RefreshPropertiesAttribute, установив для свойства или события соответствующее значение RefreshProperties.

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

Чтобы настроить выполнение сериализации значений свойства или значений свойства коллекции, следует задать атрибут DesignerSerializationVisibilityAttribute, указав для данного свойства соответствующее значение перечисления DesignerSerializationVisibility. В Visual Studio предусмотрена мощная поддержка для этой задачи. Пошаговое руководство. Сериализация коллекций стандартных типов с использованием атрибута DesignerSerializationVisibilityAttribute
Пошаговое руководство. Сериализация коллекций стандартных типов с использованием атрибута DesignerSerializationVisibilityAttribute

Чтобы указать, что тип можно подвергать сериализации, нужно задать для него атрибут SerializableAttribute. Пользовательская сериализация обеспечивается через реализацию интерфейса ISerializable или с помощью настраиваемого сериализатора. Дополнительные сведения о сериализации см. в разделе Сериализация в .NET Framework.

Дополнительные сведения о часто используемых во время разработки атрибутах см. в разделе Атрибуты времени разработки для компонентов.

Применение атрибутов

Атрибуты, используемые во время разработки, применяются по отношению к свойствам, событиям, классам и даже сборкам. В следующем примере показано применение атрибута для класса, а затем — для свойств и событий:

' The attribute is the element in angle brackets, and the parameters 
' in the attribute syntax are arguments of the constructor 
' of the attribute class.
' 
' Attributes applied at the class level.
<DefaultEvent("ValueChanged"), _
DefaultProperty("Number")> _
Public Class MyControl
   Inherits Control   
   ...
   ' Attribute applied to a property.
   <DefaultValue(False)> _
   Public Shadows ReadOnly Property TabStop() As Boolean
      ...
   End Property
   
   ' Attribute applied to a property.
   <CategoryAttribute("Data")> _
   Public ReadOnly Property Number() As Integer
      ...
   End Property 
   
   ' Attribute applied to an event.
   <Description("Raised when the Value displayed changes.")>  _
   Public Event ValueChanged As EventHandler
   ...
End Class
// The attribute is the element in brackets, and the parameters in 
// the attribute syntax are arguments of the constructor 
// of the attribute class.
// 
// Attributes applied at the class level.
[DefaultEvent("ValueChanged")]
[DefaultProperty("Number")]
public class MyControl : Control {
   ...
   // Attribute applied to a property.
   [DefaultValue(false)]
   public new bool TabStop {...
   }

   // Attribute applied to a property.
   [CategoryAttribute("Data")]
   public int Number {...}

   // Attribute applied to an event.
   [Description("Raised when the Value displayed changes.")]
   public event EventHandler ValueChanged;
}

В соответствии с принятым соглашением классы атрибутов именуются следующим образом: ИмяАтрибутаAttribute. Пространство имен System.ComponentModel содержит много базовых классов атрибутов.

Наследование и атрибуты, используемые во время разработки

Когда компонент или элемент управления является производным от базового компонента, имеющего атрибуты, используемые во время разработки, данный компонент наследует функциональные возможности, реализуемые базовым классом во время разработки. Если базовые функциональные возможности соответствуют требуемым, применять атрибуты повторно не нужно. Однако для производных компонентов можно добавлять новые атрибуты, а атрибуты одного и того же типа можно переопределять. В следующем фрагменте кода показан пользовательский элемент управления, который переопределяет свойство Text, наследуемое от элемента Control, для чего переопределяется заданный для базового класса атрибут BrowsableAttribute.

Public Class MyControl
   Inherits Control
   ' The base class has [Browsable(true)] applied to the Text property.
   <Browsable(False)>  _
   Public Overrides Property [Text]() As String
      ...
   End Property 
   ...
End Class
public class MyControl : Control {
// The base class has [Browsable(true)] applied to the Text property.
[Browsable(false)]
 public override string Text {...}
...
}

Применение атрибутов преобразователя типов, редактора типов пользовательского интерфейса и конструктора

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

<TypeConverter(GetType(MyColorConverter)), _
Editor(GetType(MyColorEditor), GetType(UITypeEditor))> _
Structure MyColor
   ...
End Structure
[ TypeConverter(typeof(MyColorConverter))]
[ Editor(typeof(MyColorEditor), typeof(UITypeEditor))] 
struct MyColor {...}

Если тип свойства не имеет связанного с ним преобразователя типов или редактора типов пользовательского интерфейса (или если требуется переопределить используемый по умолчанию преобразователь типов или редактор типов пользовательского интерфейса, связанный с типом свойства), атрибут можно задать для самого свойства. Чтобы связать преобразователь типов со свойством, при объявлении свойства следует задать атрибут TypeConverterAttribute, как это сделано в следующем примере:

<TypeConverter(GetType(PointConverter))> _
Public Property MyLocation() As Point
   ...
End Property       
[ TypeConverter(typeof(PointConverter))]
        public Point MyLocation {...}  

Чтобы связать со свойством редактор типов пользовательского интерфейса, нужно указать для свойства атрибут EditorAttribute, как это сделано в следующем примере:

<Editor(GetType(FlashTrackBarDarkenByEditor), _
GetType(UITypeEditor))>  _
Public Property DarkenBy() As Byte
   ...
End Property
[ Editor(typeof(FlashTrackBarDarkenByEditor), typeof(UITypeEditor))]
        public byte DarkenBy {...}

Конструктор можно связать с типом, но не со свойством. Чтобы связать конструктор с типом, следует применить атрибут DesignerAttribute непосредственно перед объявлением класса, как это сделано в следующем примере:

<Designer(GetType(HelpLabel.HelpLabelDesigner))> _
Public Class HelpLabel
   Inherits System.Windows.Forms.Control
   Implements System.ComponentModel.IExtenderProvider
   ...
End Class
    [Designer(typeof(HelpLabel.HelpLabelDesigner))]
    public class HelpLabel : System.Windows.Forms.Control, System.ComponentModel.IExtenderProvider {...}

Примечание

В приведенных выше примерах конструкторы для классов TypeConverterAttribute,EditorAttribute и DesignerAttribute в качестве аргументов принимают объекты Type.Данная форма конструктора указанных атрибутов работает при условии, что тип находится в той же сборке, что и используемые во время разработки классы.Если используемые во время разработки классы находятся в другой сборке, требуется другая форма конструктора атрибутов (называемая форматом с указанием сборки), как это показано в следующем примере.

<Designer("System.Windows.Forms.Design.DocumentDesigner, System.Design")>  _
Public Class MyForm
   Inherits Form
   ...
End Class
[Designer("System.Windows.Forms.Design.DocumentDesigner, System.Design")]
public class MyForm : Form {...}

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

ASP.NET предоставляет атрибут уровня сборки (TagPrefixAttribute), который позволяет разработчику элемента управления указать для элемента ASP.NET префикс тега. Префикс тега автоматически вставляется Visual Studio в директиву Register элемента управления, так что этот элемент можно использовать декларативно на странице с заранее указанным префиксом тега (<tagprefix:controlname runat = server />).

Примечание

TagPrefixAttribute работает только в визуальных конструкторах.При создании страниц ASP.NET с помощью текстового редактора, например приложения "Блокнот", для элемента управления следует самостоятельно указывать префикс тега и пространство имен в директиве Register.

В следующем примере кода показано, как применять TagPrefixAttribute. Первый аргумент конструктора атрибута указывает пространство имен, а второй задает префикс тега.

<assembly: TagPrefix("SimpleControls", "simple")>
Namespace SimpleControls
   <Designer("SimpleControl.Design.SimpleDesigner, SimpleControl")>  _
   Public Class SimpleControl
      Inherits System.Web.UI.WebControls.WebControl
      ...
   End Class 
End Namespace
[ assembly:TagPrefix("SimpleControls", "simple") ]
namespace SimpleControls {
    [
        Designer("SimpleControl.Design.SimpleDesigner, SimpleControl")
    ]
    public class SimpleControl : System.Web.UI.WebControls.WebControl {}
}

См. также

Задачи

Практическое руководство. Реализация преобразователя типов

Практическое руководство. Реализация редактора типов пользовательского интерфейса

Практическое руководство. Применение атрибутов к элементам управления Windows Forms

Основные понятия

Атрибуты в элементах управления Windows Forms

Атрибуты времени разработки для компонентов

Другие ресурсы

Расширение поддержки времени разработки

Пользовательские конструкторы