Inténtelo: crear un control WPF personalizado

Esta página es específica de proyectos WPF

Microsoft Expression Blend ofrece diversos controles de sistema y estilos simples que puede usar en las aplicaciones de Windows Presentation Foundation (WPF). Sin embargo, si estos controles o estilos no satisfacen alguna de sus necesidades específicas, puede generar un control personalizado creando una clase de Microsoft .NET heredada de una de las clases System.Windows.Controls.

[!NOTA]

Este tema contiene información relativa a las aplicaciones Windows Presentation Foundation. Para obtener información acerca de Microsoft Silverlight 1.0, vea Información general de Silverlight 1.0 y el área de recursos de Silverlight (puede estar en inglés). Vea también los ejemplos de Silverlight 1.0 incluidos en Expression Blend 2, algunos de los cuales usan clases JavaScript para definir objetos reutilizables. En el menú Ayuda, haga clic en la Pantalla de bienvenida y, a continuación, seleccione la ficha Ejemplos. Los ejemplos MagnifyingGlass, ButtonGallery y BlendPlayer son ejemplos de Silverlight 1.0.

Los procedimientos siguientes muestran cómo crear un control Button personalizado que incluya una propiedad nueva con la ruta de un archivo de imagen para que muestre una imagen. Para obtener un ejemplo de cómo crear un control de usuario sin usar código y, por lo tanto, sin propiedades personalizadas, vea Inténtelo: Crear un control de usuario de WPF.

Para obtener más información acerca de controles personalizados, incluidos ejemplos de código y XAML, vea el tema de información general de la creación de controles y el tema sobre la clase DependencyProperty en la sección sobre Windows Presentation Foundation (pueden estar en inglés) de MSDN.

Para definir un control personalizado

  1. En el panel Proyecto, busque el archivo Window1.xaml y expándalo para mostrar el archivo de código subyacente del proyecto, denominado Window1.xaml.cs. (Si eligió Microsoft Visual Basic como lenguaje cuando creó el proyecto, el archivo de código subyacente tendrá el nombre Window1.xaml.vb.) Haga doble clic en el archivo de código subyacente para abrirlo y editarlo.

    [!NOTA]

    El archivo de código subyacente se abrirá en Microsoft Visual Studio 2008 si está instalado. De no ser así, el archivo de código subyacente se abrirá en la aplicación que esté asignada a la extensión de archivo del archivo de código subyacente. Por ejemplo, si ha abierto un archivo .cs o .vb en el Bloc de notas, Expression Blend abrirá el archivo en el Bloc de notas. Para obtener ayuda acerca de cómo abrir archivos de código subyacente, vea Editar un archivo de código subyacente.

  2. En el archivo Window1.xaml.cs, pegue el código fuente de la definición de clase siguiente justo antes de la última llave de cierre (}) del archivo. En el caso de Visual Basic, pegue el código apropiado justo antes de End Namespace o justo después del último caso de End Class.

    public class ImageButton : Button 
    { 
      public ImageSource Source 
      { 
        get { return base.GetValue(SourceProperty) as ImageSource; } 
        set { base.SetValue(SourceProperty, value); } 
      } 
      public static readonly DependencyProperty SourceProperty = 
        DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImageButton)); 
    }
    
    Class ImageButton
      Inherits Button
      Public Property Source() As ImageSource
        Get
          Return CType(MyBase.GetValue(SourceProperty), ImageSource)
        End Get
        Set(ByVal value As ImageSource)
          MyBase.SetValue(SourceProperty, value)
        End Set
      End Property
      Public Shared ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register("Source", GetType(ImageSource), GetType(ImageButton))
    End Class
    
  3. Guarde el archivo de código subyacente modificado y, a continuación, cierre Visual Studio o la aplicación que haya usado para editar el archivo.

    Cc295235.alert_tip(es-es,Expression.10).gifSugerencia:

    La clase ImageButton demuestra el modelo de la propiedad de dependencia. De forma externa, la clase expone una propiedad normal Common Language Runtime (CLR, es decir, .NET) denominada Source, que es del tipo ImageSource. La clase también registra y expone un campo de propiedad de dependencia de sólo lectura denominado SourceProperty e implementa los descriptores de acceso CLR para la propiedad Source en términos de la propiedad de dependencia. Dar soporte a una propiedad CRL con una propiedad de dependencia registrada permite a WPF proporcionar una gran cantidad de servicios a la propiedad. Estos servicios incluyen estilos, enlaces de datos, herencia de valores, valores predeterminados y animación. En WPF también existe una característica denominada enlace a plantilla, que permite establecer un enlace con el valor de la propiedad desde una plantilla de control. En este tutorial se muestra cómo funciona el enlace de plantilla.

    Cc295235.alert_tip(es-es,Expression.10).gifSugerencia:

    Si prefiere guardar el código fuente de la definición de clase del control personalizado en un archivo de código fuente separado, puede hacerlo. Si lo prefiere, como alternativa a los dos pasos anteriores, puede crear un nuevo archivo denominado ImageButton.cs, pegar el código fuente en este archivo junto con la declaración del espacio de nombres y el mismo conjunto de directivas en uso del archivo de código subyacente del documento y, a continuación, agregar el nuevo archivo al proyecto (en el menú Proyecto, haga clic en Agregar elemento).

  4. Ahora debe generar el proyecto de modo que el nuevo control ImageButton aparezca en el Panel biblioteca. En el menú Proyecto de Expression Blend, haga clic en Generar proyecto (o presione CTRL+MAYÚS+B). Compruebe que la compilación se haya completado sin errores.

  5. Vuelva a la edición de Window1.xaml en Expression Blend.

  6. En el Cuadro de herramientas a lo largo del lateral izquierdo de Expression Blend, haga clic en el botón Panel bibliotecaCc295235.0224cabd-5da1-4e01-bddd-4a647401a098(es-es,Expression.10).png.

    El Panel biblioteca se abre para mostrarle todos los controles, paneles y otros elementos que puede colocar en el documento.

  7. En la ficha Controles personalizados, seleccione el control ImageButton de la lista.

    El icono Cuadro de herramientas situado encima del botón Panel biblioteca está establecido ahora en el control ImageButton y ya está seleccionado, de modo que puede dibujar el control en la mesa de trabajo.

    [!NOTA]

    Los controles personalizados no aparecerán en la ficha Controles personalizados del Panel biblioteca a menos que haya agregado el código fuente al proyecto y haya realizado una compilación (CTRL+MAYÚS+B).

  8. Con el icono ImageButton seleccionado en el Cuadro de herramientas, dibuje un objeto ImageButton haciendo clic en la mesa de trabajo y dibujando un rectángulo de selección dentro del documento.

    El objeto ImageButton se representa en la mesa de trabajo y un elemento ImageButton denominado [ImageButton] "ImageButton" se incluye en la lista como elemento secundario de LayoutRoot en Objetos y escala de tiempo, en el panel Interacción.

Cc295235.7e183f1f-37d8-4dcb-980c-19a5d61ca087(es-es,Expression.10).gifVolver al principio

Para modificar el estilo del control personalizado

  1. Para crear una plantilla de control de todos los elementos ImageButton, haga clic con el botón secundario en el nuevo ImageButton, haga clic en Editar partes del control (Plantilla) y, a continuación, haga clic en Editar una copia.

    Aparece el cuadro de diálogo Crear recurso Style.

  2. En el campo Nombre de recurso (clave) del cuadro de diálogo Crear recurso Style, en el cuadro de texto junto al primer botón de opción, escriba ImageButtonStyle.

    Esto establece un nombre de la plantilla en el diccionario de recursos de modo que pueda establecerla como plantilla de cualquier elemento ImageButton.

    [!NOTA]

    Las plantillas de control están incluidas en los estilos, por lo que el estilo que se aplica a un control incluye la apariencia (partes) y el comportamiento del control.

  3. En el campo Definir en, seleccione el botón de opción Este documento y asegúrese de que Window: Window esté seleccionado en la lista desplegable.

    El campo Definir en indica el diccionario de recursos en el que se definirá la nueva plantilla. Si selecciona Window: Window, la plantilla será visible para todos los controles ImageButton de la ventana.

  4. Haga clic en Aceptar.

    Ahora ha copiado la plantilla de control predeterminada de todos los elementos ImageButton y ha guardado la copia como un objeto ControlTemplate nuevo denominado ImageButtonStyle. La nueva plantilla se ha colocado en el diccionario de recursos, que puede ver en el nodo Window del panel Recursos.

    Con la creación de una nueva plantilla, Expression Blend cambia a un modo en que puede ver y editar la nueva plantilla. En Objetos y escala de tiempo, en el panel Interacción, la palabra Template sobre el nuevo árbol de elementos indica el ámbito actual en el que está editando. La plantilla incluye un elemento ContentPresenter que mostrará automáticamente el valor de la propiedad Content del objeto ImageButton que usa esta plantilla.

    Cc295235.alert_tip(es-es,Expression.10).gifSugerencia:

    Para salir del modo de edición de plantilla y volver al ámbito del documento, haga clic en el botón Ámbito superiorCc295235.55844eb3-ed98-4f20-aa66-a6f5b23eeb2b(es-es,Expression.10).png, que se encuentra encima del árbol de elementos junto a ImageButtonStyle.

    Para volver al modo de edición de plantillas para una plantilla existente, haga clic con el botón secundario en el elemento cuya plantilla desea editar en Objetos y escala de tiempo en el panel Interacción (en este caso, el elemento [ImageButton] "ImageButton"), haga clic en Editar partes del control (Plantilla) y, a continuación, en Editar plantilla.

  5. En Objetos y escala de tiempo, haga clic con el botón secundario en el objeto ContentPresenter, elija Agrupar en y, a continuación, haga clic en Grid.

    El objeto ContentPresenter está formado por un elemento secundario de un nuevo objeto Grid. Sin el objeto Grid, no podría agregar un segundo elemento secundario a la plantilla porque el objeto Chrome sólo puede contener un elemento secundario.

  6. Con el objeto Grid seleccionado en Objetos y escala de tiempo, busque las propiedades Width y Height en la categoría Diseño del panel Propiedades. Haga clic en el botón Opciones avanzadas de la propiedadCc295235.d6ba8f4a-b8a2-445a-af0b-a267dfade6e1(es-es,Expression.10).png junto a cada una de las propiedades y haga clic en Restablecer.

  7. Para dividir la cuadrícula en dos columnas, haga doble clic en el objeto Grid en Objetos y escala de tiempo para activar la cuadrícula y, a continuación, con la herramienta SelecciónCc295235.2ff91340-477e-4efa-a0f7-af20851e4daa(es-es,Expression.10).png seleccionada en el Cuadro de herramientas, mueva el puntero del mouse sobre el área gruesa y azul de la regla de la parte superior de Grid en la mesa de trabajo. Una regla de columna naranja seguirá al puntero del mouse para indicar dónde se colocará el nuevo divisor de columna si hace clic.

    Haga clic para crear un nuevo divisor de columna en el medio de Grid.

    Aparece un divisor de columna azul dentro de Grid.

  8. Seleccione la herramienta ImagenCc295235.0594f05b-2193-4385-86a0-2d352cacfe55(es-es,Expression.10).png en la ficha Controles del Panel biblioteca (active la casilla de verificación Mostrar todo). Con el elemento Grid aún activado en Objetos y escala de tiempo en el panel Interacción, dibuje un nuevo elemento Image en la columna derecha de Grid.

  9. Con el nuevo elemento Image seleccionado en Objetos y escala de tiempo, mire en Propiedades comunes en el panel Propiedades. Haga clic en el botón Opciones avanzadas de la propiedadCc295235.d6ba8f4a-b8a2-445a-af0b-a267dfade6e1(es-es,Expression.10).png situado a la derecha de la propiedad Source, seleccione Enlace de plantillas y, a continuación, haga clic en Source.

    Acaba de enlazar mediante una plantilla la propiedad Source de Image a la propiedad Source del elemento ImageButton que usa esta plantilla.

  10. Ha terminado de editar la plantilla. Para salir al ámbito del elemento raíz, haga clic en Ámbitosuperior en Objetosyescala de tiempo.

  11. Con el elemento ImageButton seleccionado en Objetosyescala de tiempo, busque la propiedad Source en la categoría Varios del panel Propiedades y establézcala como la ruta de acceso de un archivo de imagen del equipo.

    La imagen se muestra a la derecha del control ImageButton.

Cc295235.7e183f1f-37d8-4dcb-980c-19a5d61ca087(es-es,Expression.10).gifVolver al principio

Para aplicar el estilo a otro control personalizado

  1. En la ficha Controlespersonalizados del Panelbiblioteca, seleccione el control ImageButton. Dibuje un nuevo control ImageButton en la mesa de trabajo.

  2. Haga clic con el botón secundario en el nuevo ImageButton, haga clic en Editar partes del control (Plantilla) luego en Aplicar recurso y, a continuación, haga clic en el nombre del estilo, ImageButtonStyle.

    El estilo ImageButtonStyle se aplica al nuevo control ImageButton. Busque la propiedad Source en la categoría Varios del panel Propiedades y establézcala como la ruta de acceso de un archivo de imagen del equipo.

    [!NOTA]

    Como alternativa, puede agregar a la mesa de trabajo un ImageButton que ya tenga aplicado un estilo mediante la plantilla. En la ficha Estilos locales del Panel biblioteca, seleccione ImageButtonStyle y, a continuación, dibuje el ImageButton con el estilo aplicado en la mesa de trabajo.

Cc295235.7e183f1f-37d8-4dcb-980c-19a5d61ca087(es-es,Expression.10).gifVolver al principio

Opciones avanzadas: aplicar descripciones a propiedades personalizadas

  1. En la parte superior del archivo de código subyacente (Window1.xaml.cs), agregue una referencia al espacio de nombres System.ComponentModel.

    Los atributos Description y Category usados más adelante se definen en este espacio de nombres.

  2. Pegue la línea siguiente (en negrita) antes de la definición de clase:

    [Description("Represents a custom button control that responds to a Click event. Displays an image using a custom Source property if the Source property is bound to an Image in the template.")]
    public class ImageButton : Button
    
    <Description("Represents a custom button control that responds to a Click event. Displays an image using a custom Source property if the Source property is bound to an Image in the template.")> _
    Class ImageButton
    
  3. Pegue la línea siguiente (en negrita) antes de la definición de propiedad personalizada:

    [Description("The image displayed in the button if there is an Image control in the template whose Source property is template-bound to the ImageButton Source property."), Category("Common Properties")] 
        public ImageSource Source
    
    <Description("The image displayed in the button if there is an Image control in the template whose Source property is template-bound to the ImageButton Source property."), Category("Common Properties")> _ 
        Public Property Source() As ImageSource
    

    El atributo Category configura el lugar en que se mostrará la propiedad en el panel Propiedades.

  4. Vuelva a generar el proyecto (CTRL+MAYÚS+B).

    Ahora, la propiedad Source de ImageButton aparecerá en la categoría Propiedades comunes del panel Propiedades y las descripciones aparecerán como información sobre herramientas cuando mueva el puntero del mouse sobre la propiedad y sobre el control en el Panel biblioteca.

Cc295235.7e183f1f-37d8-4dcb-980c-19a5d61ca087(es-es,Expression.10).gifVolver al principio

Opciones avanzadas: configurar un control para que muestre una imagen predeterminada

Puede agregar código al constructor de cualquier control personalizado que establezca una propiedad en un valor predeterminado cuando se dibuje el control en la mesa de trabajo y, por lo tanto, en el modo de diseño. Si establece una propiedad con el procedimiento siguiente, sólo afectará a lo que se ve en la mesa de trabajo y no a lo que se ve cuando se ejecuta la aplicación. Esto es útil cuando el contenido no está disponible para el control en el modo de diseño pero está disponible cuando se ejecuta la aplicación; por ejemplo, cuando el contenido proviene de una base de datos o servicio Web. En este caso, la propiedad Source de un ImageButton en la mesa de trabajo se establece en el nombre de un archivo de imagen del proyecto hasta que se configure explícitamente.

  1. En el archivo de código subyacente (Window1.xaml.cs), pegue las siguientes líneas de código (en negrita) después de la definición de la propiedad:

    [!NOTA]

    Cambie el nombre del archivo (Sunset.jpg) en el código siguiente por el nombre de un archivo de imagen del proyecto. Para agregar un archivo de imagen al proyecto, haga clic con el botón secundario en el nombre del proyecto en Archivos, en el panel Proyecto, y, a continuación, haga clic en Agregar elemento existente.

    public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImageButton));
    
    // Constructor:public ImageButton(){   if (DesignerProperties.GetIsInDesignMode(this))   {      this.Source = new BitmapImage(new Uri("Sunset.jpg", UriKind.Relative));   }}
    
    Public Shared ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register("Source", GetType(ImageSource), GetType(ImageButton))
    
    Public Sub New()    If DesignerProperties.GetIsInDesignMode(Me) Then        Me.Source = New BitmapImage(New Uri("Sunset.jpg", UriKind.Relative))    End IfEnd Sub
    
  2. Vuelva a generar el proyecto (CTRL+MAYÚS+B).

    Ahora, cuando agregue a la mesa de trabajo un ImageButton que use el estilo que ha creado, aparecerá una imagen predeterminada en el botón.

    [!NOTA]

    No podrá establecer la propiedad Source en ningún otro valor mientras se encuentre en modo de diseño.

Cc295235.7e183f1f-37d8-4dcb-980c-19a5d61ca087(es-es,Expression.10).gifVolver al principio