Atributos y compatibilidad en tiempo de diseño

Actualización: noviembre 2007

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 atributo DesignerAttribute asocia un diseñador a un tipo. Un atributo TypeConverterAttribute asocia un convertidor de tipos a un tipo o a un miembro de tipo. EditorAttribute asocia un editor de tipos de la interfaz de usuario a un tipo o 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 al cargar un componente en tiempo de diseño mediante la aplicación de un atributo DefaultValueAttribute a una propiedad. 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 de la ventana Propiedades

Para indicar si una propiedad o evento debe mostrarse en una ventana Propiedades, aplíquele BrowsableAttribute. También se puede modificar el conjunto de propiedades y eventos expuestos en la ventana 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 evento en la ventana Propiedades, aplicando un atributo CategoryAttribute a la propiedad o evento. Se puede especificar que se muestre una descripción de una propiedad o evento en la ventana Propiedades aplicando 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 de sólo lectura o de lectura y 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 la ventana Propiedades aplicando un atributo ParenthesizePropertyNameAttribute a la propiedad con un valor true.

Se puede especificar si se debe notificar a una propiedad que tiene propiedades anidadas o secundarias cuándo cambia el valor de la propiedad anidada aplicando un 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 si se debe redibujar la vista del diseñador aplicando un atributo RefreshPropertiesAttribute con un valor de 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 aplicando un atributo DesignerSerializationVisibilityAttribute con un valor de enumeración DesignerSerializationVisibility apropiado a la propiedad. Visual Studio es ampliamente compatible con esta tarea.

Se puede especificar que un tipo se pueda serializar aplicando SerializableAttribute al tipo. Se puede proporcionar serialización personalizada implementando la interfaz ISerializable o proporcionando un serializador personalizado. Para obtener más información sobre serialización, vea Serialización.

Para obtener más información sobre los atributos que se usan habitualmente en tiempo de diseño, vea Atributos en 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
// 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 convenio, las clases de atributos se denominan nombreDeAtributoAttribute. El espacio de nombres System.ComponentModel contiene muchas clases de atributo base.

Atributos en tiempo de diseño y herencia

Cuando se deriva un componente o un control de un componente base que tiene atributos en 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 invalida la propiedad Text heredada de Control, invalidando el atributo BrowsableAttribute aplicado a 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
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 en 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 código de ejemplo siguiente se muestra un atributo TypeConverterAttribute aplicado a un tipo.

<TypeConverter(GetType(MyColorConverter)), _
Editor(GetType(MyColorEditor), GetType(UITypeEditor))> _
Structure MyColor
   ...
End Structure
[ 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 muestra en el ejemplo de código siguiente.

<TypeConverter(GetType(PointConverter))> _
Public Property MyLocation() As Point
   ...
End Property       
[ 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 muestra en el ejemplo de código siguiente.

<Editor(GetType(FlashTrackBarDarkenByEditor), _
GetType(UITypeEditor))>  _
Public Property DarkenBy() As Byte
   ...
End Property
[ 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 de código siguiente.

<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 {...}
Nota:

En los ejemplos anteriores, 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 en 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
[Designer("System.Windows.Forms.Design.DocumentDesigner, System.Design")]
public class MyForm : Form {...}

Atributo en 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 lo introduce automáticamente 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 (<tagprefix:nombreDeControl runat = server />).

Nota:

TagPrefixAttribute sólo funciona 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.

En el ejemplo de código siguiente se muestra cómo aplicar 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
[ assembly:TagPrefix("SimpleControls", "simple") ]
namespace SimpleControls {
    [
        Designer("SimpleControl.Design.SimpleDesigner, SimpleControl")
    ]
    public class SimpleControl : System.Web.UI.WebControls.WebControl {}
}

Vea también

Tareas

Cómo: Implementar un convertidor de tipos

Cómo: Implementar un editor de tipos de interfaz de usuario

Cómo: Aplicar atributos en controles de formularios Windows Forms

Conceptos

Atributos en controles de formularios Windows Forms

Atributos en tiempo de diseño para componentes

Otros recursos

Ampliar compatibilidad en tiempo de diseño

Diseñadores personalizados