Atributos y funcionalidad en tiempo de diseño
Las extensiones de funcionalidad en tiempo de diseño se implementan normalmente en código que existe independientemente del código para un componente. Se utilizan variedad de atributos para asociar proveedores de funcionalidad en tiempo de diseño con un tipo o un miembro individual de un tipo.
Atributos para asociar la funcionalidad en tiempo de diseño
Un DesignerAttribute asocia un diseñador con un tipo. Un TypeConverterAttribute asocia un convertidor de tipos con un tipo o un miembro de un tipo. Un EditorAttribute asocia un editor de tipos con interfaz de usuario con un tipo o un miembro de tipo.
Atributos para personalizar la inicialización de componentes
Se puede especificar un valor predeterminado para una propiedad que se va a establecer cuando se carga un componente en tiempo de diseño al aplicar un atributo DefaultValueAttribute a una propiedad. Un atributo DefaultValueAttribute reemplaza un valor establecido por código de inicialización de componentes en tiempo de diseño, pero el atributo no reemplaza un valor establecido por un diseñador.
Atributos para personalizar el comportamiento del examinador de propiedades
Se puede indicar si una propiedad o evento debe ser mostrada en un examinador de propiedades aplicándole un atributo BrowsableAttribute. También se puede modificar el conjunto de propiedades y eventos expuestos al examinador de propiedades en tiempo de diseño, utilizando un diseñador que implemente la interfaz IDesignerFilter. Se puede especificar la categoría en la que se debe mostrar una propiedad o un evento en un examinador de propiedades mediante la aplicación de un atributo CategoryAttribute a la propiedad o evento. Se puede especificar que se muestre una descripción de la propiedad o evento en el examinador de categorías mediante la aplicación de un atributo DescriptionAttribute a la propiedad o evento.
Se puede especificar si una propiedad sólo puede establecerse en tiempo de diseño, aplicando un atributo DesignOnlyAttribute a la propiedad. Se puede especificar si una propiedad es sólo de lectura o sólo de escritura en tiempo de diseño, aplicando un atributo ReadOnlyAttribute a la propiedad.
Se puede especificar si se debe mostrar una propiedad con su nombre entre paréntesis en el examinador de propiedades aplicando un atributo ParenthesizePropertyNameAttribute a la propiedad que tiene el valor true.
Se puede especificar si se debe notificar a una propiedad con propiedades anidadas o secundarias, cuando cambia el valor de los cambios de propiedad anidados, aplicando el atributo NotifyParentPropertyAttribute a la propiedad anidada que debe provocar la notificación.
Se puede especificar si se deben actualizar o no las propiedades de un componente, o se debe redibujar la vista del diseñador, mediante la aplicación de un atributo RefreshPropertiesAttribute con un valor RefreshProperties apropiado a una propiedad o un evento.
Atributos para personalizar un comportamiento de serialización en tiempo de diseño
Se puede especificar si se serializan los valores de una propiedad, o si se serializan los valores de una propiedad de colección, mediante la aplicación de un atributo DesignerSerializationVisibilityAttribute con un valor de enumeración apropiado DesignerSerializationVisibility a la propiedad.
Se puede especificar que un tipo se pueda serializar mediante la aplicación de un atributo SerializableAttribute al tipo. Se puede proporcionar una serialización personalizada al implementar la interfaz ISerializable o proporcionar un serializador personalizado. Para obtener más información sobre la serialización, vea Serializar objetos.
Para obtener más información sobre los atributos más frecuentes en tiempo de diseño, vea Atributos de tiempo de diseño para componentes.
Aplicar atributos
Los atributos en tiempo de diseño se aplican a propiedades, eventos, clases e incluso a ensamblados. En el código siguiente, se muestran atributos aplicados a una clase y después a propiedades y eventos.
' 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
[C#]
// 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;
}
Por convención, las clases de atributos se denominan NombreDeAtributoAttribute. El espacio de nombres System.ComponentModel contiene numerosas clases base de atributo .
Atributos de tiempo de diseño y herencia
Cuando se deriva un componente o un control de un componente base que tiene atributos de tiempo de diseño, el componente hereda la funcionalidad en tiempo de diseño de la clase base. Si la funcionalidad básica es adecuada para sus planes, no tiene que volver a aplicar los atributos. No obstante, siempre puede reemplazar atributos del mismo tipo o aplicar atributos adicionales al componente derivado. En el siguiente fragmento de código se muestra un control personalizado que reemplaza a la propiedad Text heredada de Control al reemplazar el atributo BrowsableAttribute aplicado en la clase base.
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
[C#]
public class MyControl : Control {
// The base class has [Browsable(true)] applied to the Text property.
[Browsable(false)]
public override string Text {...}
...
}
Aplicar un atributo de convertidor de tipos, editor con tipos de interfaz de usuario o diseñador
Para asociar un proveedor de funcionalidad de tiempo de diseño con un tipo o miembro de un tipo, aplique el tipo apropiado de atributo a la línea sobre la declaración de clase o declaración de miembro. En el siguiente ejemplo de código se muestra un atributo TypeConverterAttribute aplicado a un tipo.
<TypeConverter(GetType(MyColorConverter)), _
Editor(GetType(MyColorEditor), GetType(UITypeEditor))> _
Structure MyColor
...
End Structure
[C#]
[ TypeConverter(typeof(MyColorConverter))]
[ Editor(typeof(MyColorEditor), typeof(UITypeEditor))]
struct MyColor {...}
Si el tipo de una propiedad no tiene asociado un convertidor de tipos o un editor de tipos con interfaz de usuario, o si desea reemplazar el convertidor de tipos predeterminado o el editor de tipos con interfaz de usuario asociado con el tipo de una propiedad, se puede aplicar un atributo a la propiedad misma. Para asociar un convertidor de tipos a una propiedad, aplique un atributo TypeConverterAttribute a la declaración de propiedad, como se observa en el ejemplo de código siguiente.
<TypeConverter(GetType(PointConverter))> _
Public Property MyLocation() As Point
...
End Property
[C#]
[ TypeConverter(typeof(PointConverter))]
public Point MyLocation {...}
Para asociar un editor de tipos de interfaz de usuario a una propiedad, aplique un atributo EditorAttribute a la propiedad, como se observa en el ejemplo siguiente de código.
<Editor(GetType(FlashTrackBarDarkenByEditor), _
GetType(UITypeEditor))> _
Public Property DarkenBy() As Byte
...
End Property
[C#]
[ Editor(typeof(FlashTrackBarDarkenByEditor), typeof(UITypeEditor))]
public byte DarkenBy {...}
Se puede asociar un diseñador con un tipo pero no con una propiedad. Para asociar un diseñador a un tipo, aplique un atributo DesignerAttribute directamente sobre la declaración de clase, como se muestra en el ejemplo siguiente de código.
<Designer(GetType(HelpLabel.HelpLabelDesigner))> _
Public Class HelpLabel
Inherits System.Windows.Forms.Control
Implements System.ComponentModel.IExtenderProvider
...
End Class
[C#]
[Designer(typeof(HelpLabel.HelpLabelDesigner))]
public class HelpLabel : System.Windows.Forms.Control, System.ComponentModel.IExtenderProvider {...}
Nota En estos ejemplos, los constructores de las clases TypeConverterAttribute, EditorAttribute y DesignerAttribute aceptan objetos System.Type como argumentos Esta forma de constructor de estos atributos funciona si el tipo se encuentra en el mismo ensamblado que las clases de tiempo de diseño. Si las clases en tiempo de diseño se encuentran en un ensamblado diferente, se requiere una forma distinta del constructor de atributos (denominada formato de ensamblado calificado), como se muestra en el ejemplo siguiente de código.
<Designer("System.Windows.Forms.Design.DocumentDesigner, System.Design")> _
Public Class MyForm
Inherits Form
...
End Class
[C#]
[Designer("System.Windows.Forms.Design.DocumentDesigner, System.Design")]
public class MyForm : Form {...}
Atributo de tiempo de diseño en el nivel de ensamblado
ASP.NET proporciona un atributo de nivel de ensamblado (System.Web.UI.TagPrefixAttribute) que permite que un programador de controles especifique un prefijo de etiqueta para un control ASP.NET. El prefijo de etiqueta se introduce automáticamente mediante Visual Studio .NET en la directiva Register del control, por lo que el control se puede utilizar de manera declarativa en la página con el prefijo de etiqueta previamente especificado (<prefijoDeEtiqueta:nombreDeControl ... runat = server />).
Nota TagPrefixAttribute funciona sólo en diseñadores visuales. Si crea páginas ASP.NET con un editor de texto como Bloc de notas, necesita especificar el prefijo de etiqueta y el espacio de nombres manualmente en la directiva Register del control.
El ejemplo siguiente muestra cómo se aplica el atributo TagPrefixAttribute. El primer argumento del constructor del atributo especifica el espacio de nombres y el segundo especifica el prefijo de etiqueta.
<assembly: TagPrefix("SimpleControls", "simple")>
Namespace SimpleControls
<Designer("SimpleControl.Design.SimpleDesigner, SimpleControl")> _
Public Class SimpleControl
Inherits System.Web.UI.WebControls.WebControl
...
End Class
End Namespace
[C#]
[ assembly:TagPrefix("SimpleControls", "simple") ]
namespace SimpleControls {
[
Designer("SimpleControl.Design.SimpleDesigner, SimpleControl")
]
public class SimpleControl : System.Web.UI.WebControls.WebControl {...}
}
Vea también
Mejorar la compatibilidad en tiempo de diseño | Implementar un convertidor de tipos | Implementar un editor de tipos de interfaz de usuario | Diseñadores personalizados