MSDN Magazine > Home > Issues > 2007 > May >  WPF: Personalización de controles para Win...
WPF
Personalización de controles para Windows Presentation Foundation
Shawn Wildermuth

En este artículo se analizan los siguientes temas:
  • Controles compuestos
  • Estilos y plantillas
  • Propiedades personalizadas
  • Controles personalizados
En este artículo se utilizan las siguientes tecnologías:
Windows Presentation Foundation
El alcance del modelo del control en Windows Presentation Foundation no está completamente definido, pero es imposible suministrar todos los controles que se podrían necesitar. Por este motivo existe la creación de controles. En este artículo le muestro cómo personalizar controles existentes usando Windows® Presentation Foundation y cómo crear controles (o elementos) para usar en sus proyectos.
Antes de desarrollar un control personalizado, pregúntese si realmente lo necesita. En Windows Presentation Foundation, la composición, el estilo y las plantillas habilitan la personalización de los controles existentes hasta un nivel sin precedentes en tecnologías anteriores. Antes de decidir la creación de un control nuevo, revisemos rápidamente estos tres métodos para personalizar controles.

Utilizar la composición
Un requisito habitual es crear un control compuesto: que incluya más de un control. Suponga que tiene un botón para iniciar la reproducción de un vídeo. El XAML y el control se muestran en la Figura 1.
<StackPanel>
  <Button Height=”50” Width=”50” Content=”Play” />
  <Polygon HorizontalAlignment=”Center” 
           Points=”0,0 0,26 17,13”
           Fill=”Black” />
</StackPanel>
Es necesario que pueda tomar el icono del juego y ponerlo en el botón. Puede usar la composición para incrustar los elementos XAML dentro de otros. Por ejemplo, puede cambiar el XAML para crear la etiqueta y el icono como contenido del botón. Al colocar estos elementos dentro de un contenedor (en este caso StackPanel) dentro del botón, éstos se asignan a la propiedad de contenido de la clase de botón, tal como se muestra en la Figura 2. De ello resulta un botón que funciona como cualquier otro pero con el contenido que usted ha colocado.
<StackPanel>
  <Button Height=”50” Width=”50”>
    <StackPanel>
      <TextBlock>Play</TextBlock>
      <Polygon Points=”0,0 0,26 17,13”
               Fill=”Black” />
    </StackPanel>
  </Button>
</StackPanel>
Es sencillo utilizar la composición para crear controles como éste. A diferencia de lo que ocurre en tecnologías de presentación como Windows Forms, Visual Basic ® 6,0 y MFC, la mayoría de los controles son contenedores de otros controles. No es necesario escribir un control personalizado cuando lo que usted realmente necesita es uno compuesto.

Utilizar los estilos
¿Qué sucede si todo lo que usted necesita es cambiar la apariencia del control? La respuesta está en los estilos. Puede especificar un estilo de botón que tenga un borde rojo creando un estilo que sea así.
<StackPanel>
  <StackPanel.Resources>
    <Style TargetType=”Button” x:Key=”RedButton”>
      <Setter Property=”BorderBrush” Value=”Red” />
    </Style>
  </StackPanel.Resources>
  ...
</StackPanel>
Puede cambiar el borde de unos botones concretos asignándoles un estilo, tal como se muestra en la Figura 3. El primer botón representa la apariencia estándar, mientras que el segundo se enlaza a un estilo compartido.
Figura 3
<Button Height=”50” Width=”50”>
  <StackPanel>
    <TextBlock>Play</TextBlock>
    <Polygon Points=”0,0 0,26 17,13”
             Fill=”Black” />
  </StackPanel>
</Button>
<Button Height=”50” Width=”50” Style=”{StaticResource RedButton}”>
  <StackPanel>
    <TextBlock>Play</TextBlock>
    <Polygon Points=”0,0 0,26 17,13”
             Fill=”Black” />
  </StackPanel>
</Button>
Puede usar los estilos incluso para cambiar la apariencia de todas las instancias de un cierto tipo de elemento de XAML de un contenedor. Por ejemplo, en lugar de crear un estilo reutilizable para cambiar el botón, puede crear un estilo que especifique el aspecto de todos ellos, tal como se muestra en la Figura 4. Este ejemplo establece el fondo de todos botones en gris/verde/gris degradado. El estilo de este ejemplo omite la clave de estilo, por esta razón afecta a todos los elementos especificados en el atributo TargetType.
Figura 4
<StackPanel>
  <StackPanel.Resources>

    <Style TargetType=”Button”>
      <Setter Property=”Background”>
        <Setter.Value>
          <LinearGradientBrush>
            <GradientStop Color=”#DDDDDD” Offset=”0” />
            <GradientStop Color=”#88FF88” Offset=”.6” />
            <GradientStop Color=”#EEEEEE” Offset=”1” />
          </LinearGradientBrush>
        </Setter.Value>
      </Setter>
    </Style>

  </StackPanel.Resources>

  <Button Height=”50” Width=”50”>
    <StackPanel>
      <TextBlock>Play</TextBlock>
      <Polygon Points=”0,0 0,26 17,13”
               Fill=”Black” />
    </StackPanel>
  </Button>

  <Button Height=”50” Width=”50”>
    <StackPanel>
      <TextBlock>Play</TextBlock>
      <Polygon Points=”0,0 0,26 17,13”
               Fill=”Black” />
    </StackPanel>
  </Button>

</StackPanel>

Uso de plantillas
Los estilos están limitados a la configuración de las propiedades predeterminadas en elementos XAML. Por ejemplo, cuando en los ejemplos anteriores he establecido el BorderBrush, he podido especificar el pincel pero no el ancho del borde. Para una libertad completa de una apariencia del control, necesita usar plantillas. Para ello, debe crear un estilo y especificar la propiedad de plantilla (consulte la Figura 5). El valor de la propiedad de plantilla pasa a ser un elemento ControlTemplate que especifica cómo redactar el control. En este ejemplo he especificado un botón en forma de círculo con el icono de reproducción en el centro, colocando el icono de reproducción sobre un elemento elipse. El nuevo botón de plantilla aparece junto a un botón normal.
Figura 5
<StackPanel>
  <StackPanel.Resources>

    <Style TargetType=”{x:Type Button}” x:Key=”PlayButton” >
      <Setter Property=”Template”>
        <Setter.Value>
          <ControlTemplate TargetType=”{x:Type Button}”>
            <Grid>
              <Ellipse Width=”{TemplateBinding Width}”
                       Height=”{TemplateBinding Height}”
                       Stroke=”DarkGray”
                       VerticalAlignment=”Top”
                       HorizontalAlignment=”Left”
                       Fill=”LightGray” />
              <Polygon Points=”18,12 18,38 35,25”
                       Fill=”Black” />
            </Grid>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

  </StackPanel.Resources>

  <Button Height=”50” Width=”50”>Normal Button</Button>
  <Button Height=”50” Width=”50” Style=”{StaticResource PlayButton}” />

</StackPanel>
Al final, los estilos y las plantillas aún le siguen permitiendo sólo cambiar la apariencia de un control. Para agregar el comportamiento y otras características al botón, hace falta crear un control personalizado.

Creación de controles
El primer paso que debe dar antes de escribir su propio control es decidir qué método va a usar para crearlo. Existen dos maneras principales de crear controles en Windows Presentation Foundation: los controles de usuario y los controles personalizados. Ambos enfoques ofrecen ventajas.
Con los controles de usuario, se obtiene un modelo de desarrollo sencillo semejante al desarrollo de aplicaciones de Windows Presentation Foundation. Los controles de usuario son preferibles cuando se necesita crear un control con componentes existentes y no hace falta la personalización compleja (como con plantillas y estilos). Los controles personalizados son una opción más adecuada cuando se desea un control total sobre la apariencia, cuando se necesita una compatibilidad de representación especial, o si se desea que el control sea un contenedor de otros controles.
Si duda al elegir el tipo de control, elija un control de usuario. Cuando el control de usuario llega a sus límites de funcionalidad, puede pasar a un control personalizado con pocas dificultades.
Lo primero que debe hacer al crear un control de usuario es agregar un elemento nuevo a su proyecto. Si hace clic al proyecto con el botón secundario y luego a Agregar, quizás sienta la tentación de escoger la opción de Control de Usuario del menú contextual. Lamentablemente, esta función intentará crear un control de usuario nuevo de Windows Forms. En su lugar, escoja la opción Agregar nuevo elemento. En el diálogo Agregar nuevo elemento, escoja el elemento Control de Usuario (WPF).
Al crear el control de usuario nuevo se crea un archivo XAML y un archivo de código de seguridad. El archivo XAML es semejante al archivo principal, creado con proyectos nuevos de Windows Presentation Foundation; la diferencia es que el elemento raíz del archivo XAML nuevo es un elemento UserControl. Dentro del elemento UserControl debe crear el contenido que configurará su control.
Para este ejemplo, continúe con el mismo XAML utilizado anteriormente para crear una plantilla para un control PlayButton. Este nuevo control se vinculará a un MediaElement para controlar la reproducción o la pausa de algunos multimedia. La figura 6 muestra el XAML de PlayButton.
Figura 7 PlayButton en una ventana WPF 
<!-- PlayButton.xaml --> 
<UserControl x:Class=”CustomWPF.PlayButton”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>

  <Grid>

    <Ellipse Width=”50” Height=”50” 
             Stroke=”DarkGray”
             VerticalAlignment=”Top”
             HorizontalAlignment=”Left”
             Name=”ButtonBack”                       
             Fill=”LightGray” />
    <Path Name=”PlayIcon” Fill=”Black”
          Data=”M18,12 18,38 35,25”/>
    <Path Name=”PauseIcon” Fill=”Black” Opacity=”0”
          Data=”M15,12 15,38 23,38 23,12z M27,12 27,38 35,38 35,12” />

  </Grid>

</UserControl>
A partir del ejemplo de la plantilla he agregado una ruta de acceso nueva: PauseIcon. Como el icono para pausar los medios no podía representarse como un polígono, era más sencillo cambiar simplemente PlayIcon a una ruta de acceso para que se pueda tratar cada icono como un objeto de la ruta en el código subyacente. Quiero poder controlar un elemento de MediaElement con la pausa o reproducción de los medios cuando se haya hecho clic en el botón y también con el cambio de icono para representar la acción correctamente (pausa o reproducción) cuando se haya hecho clic en el botón.
Antes de agregar esa lógica, asegúrese de que mi botón se presenta correctamente y que se puede mostrar en una ventana. En tal caso, quiero mostrar el control nuevo en una ventana. Antes de poder usar cualquier elemento personalizado (control de usuario o control personalizado) en un documento XAML, debe crearle una referencia. Si el elemento personalizado se encuentra en el mismo proyecto que el resto de su XAML, puede crear la referencia simplemente agregando una declaración de espacio de nombres XML. En las líneas siguientes del código he creado una declaración de espacio de nombres (xmlns:cust) que especifica un espacio de nombres Common Language Runtime (CLR) donde se encuentra el control.
<!-- MainWindow.xaml -->
<Window x:Class=”Tester.MainWindow”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:cust=”clr-namespace:CustomWPF“
    Title=”Control Viewer” 
    Height=”100” Width=”200”>

  <!-- ... -->

</Window>
El espacio de nombres CLR (CustomWPF) especificado en la declaración de espacio de nombres XML coincide con el espacio de nombres CLR verdadero del control (CustomWPF). Si el control que usted quiere usar se encuentra en otro ensamblado, también debe tener en cuenta el nombre de ensamblado en la declaración de espacio de nombres. La declaración del espacio de nombres XML no importa el ensamblado automáticamente en su proyecto, debe agregarle manualmente una referencia al ensamblado.
<!-- MainWindow.xaml -->
<Window x:Class=”Tester.MainWindow”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:cust=”clr-namespace:CustomWPF;assembly=CustomWPF”
    Title=”Control Viewer” 
    Height=”100” Width=”200”>

  <!-- ... -->

</Window>
Una vez tenga la referencia para el espacio de nombres XML, la puede usar para crear las instancias de su control de usuario nuevo. Para ello, utilice el nombre de la declaración de espacio de nombres. Es decir, el alias de espacio de nombres XML, no el de CLR. Después del alias de espacio de nombre debe especificar el nombre verdadero del control. De esta forma se asegura de que el nombre usado en el archivo XAML coincida con el nombre de la clase. Para agregar una instancia de la clase PlayButton a XAML, debe especificar cust:PlayButton como nombre de elemento.
<StackPanel>
  <TextBlock HorizontalAlignment=”Center”>User Control:</TextBlock>
  <cust:PlayButton />
</StackPanel>
Ahora puede ver el control PlayButton hospedado en una ventana típica de Windows Presentation Foundation como en la Figura 7.

Propiedades personalizadas
Al crear los controles descubrirá que es necesario implementar las propiedades para administrar tanto la apariencia del control como su comportamiento en el tiempo de ejecución. Por ejemplo, sería necesario que el control PlayButton pudiera obtener y establecer el color del icono. Para ello, puede crear una propiedad CLR sencilla como se muestra en la Figura 8 (tenga en cuenta que el código de ejemplo de Visual Basic se encuentra en la descarga de este artículo).
// PlayButton.xaml.cs
public partial class PlayButton : System.Windows.Controls.UserControl
{
  // ...

  Brush _iconColor = Brushes.Black;

  public Brush IconColor
  {
    get {return _iconColor; }
    set
    {
      _iconColor = value;
      PlayIcon.Fill = _iconColor;
      PauseIcon.Fill = _iconColor;
    }
  }
}
Las propiedades CLR sencillas como la de IconColor funcionan bastante bien. Las puede establecer en el XAML utilizando simplemente el nombre de la propiedad:
<cust:PlayButton IconColor=”Black” />
Sin embargo, las propiedades sencillas no son suficientes para la mayoría de los controles, debido a que éstos no admiten características avanzadas como los enlaces de datos o la compatibilidad con animaciones. Por ejemplo, no sirven para especificar el IconColor de su control mediante enlaces de datos al color de relleno de un rectángulo en XAML, como se muestra en la Figura 9.
<!-- MainWindow.xaml -->
<Window x:Class=”Tester.MainWindow”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:cust=”clr-namespace:CustomWPF;assembly=CustomWPF”
    Title=”Control Viewer” 
    Height=”100” Width=”200”>

  <StackPanel>
    <Rectangle Name=”theRect” Fill=”Red” />
    <TextBlock>User Control:</TextBlock>

    <!-- Simple Assignment Works -->
    <cust:PlayButton IconColor=”Blue” />

    <!—Data Binding Does Not -->
    <cust:PlayButton 
      IconColor=”{Binding ElementName=theRect, Path=Fill}” />

  </StackPanel>
</Window>
Para aprovechar todas las características disponibles es necesario usar una propiedad de dependencia en vez de una propiedad CLR sencilla. Las propiedades de dependencia permiten a varios medios establecer el valor de un elemento, entre ellos las animaciones y los enlaces de datos. Para implementar una, cree un campo estático de DependencyProperty (compartido en Visual Basic) en el control con el método DependencyProperty.Register. Este método registra su propiedad y devuelve una instancia del DependencyProperty creado.
Una vez tenga el campo DependencyProperty lo puede usar para establecer y obtener la propiedad utilizando los métodos Getvalue/Setvalue de su control. Por ejemplo, puede cambiar la propiedad de IconColor de PlayButton a un DependencyProperty como se muestra en la Figura 10.
Observe que he quitado de la clase el campo Pincel. DependencyProperty almacena el valor de cada instancia y también los metadatos sobre la propiedad. Esto significa que cada instancia de PlayButton no necesita tener su propio campo para almacenar los datos de la propiedad.
Ahora que usted tiene un DependencyProperty, lo puede usar en enlaces de datos o en animación. Actualmente no hay forma de determinar que la propiedad ha cambiado ni existe ningún valor predeterminado. Como la configuración del valor de la propiedad no se enruta a través de la propiedad pública (es la propiedad de CLR la que contiene el DependencyProperty, y no al revés), cuando se cambia este valor, usted no puede usar el descriptor de acceso fijo para cambiar el color de icono. Necesita agregar un evento al que llamar cuando cambie la propiedad. Para ello, especifique un método estático o compartido al que llamar cuando la propiedad cambie al registrar el DependencyProperty. Puede modificar el registro para incluir un objeto FrameworkPropertyMetadata que especifique tanto el valor predeterminado como una devolución de llamada de cambio, como se muestra aquí:
public static readonly DependencyProperty IconColorProperty =
        DependencyProperty.Register(
            “IconColor”, 
            typeof(Brush), 
    typeof(PlayButton),
    new FrameworkPropertyMetadata(Brushes.Black,
    new PropertyChangedCallback(OnIconColorChanged
    )));
Finalmente, necesita implementar la devolución de llamada. Esta devolución de llamada es un método estático (o compartido) de su control que acepta el objeto cambiado así como los argumentos que especifican los valores antiguos y nuevos. Normalmente se llama a un método en el objeto cambiado para actualizarlo. Por ejemplo, si IconColor ha cambiado, será necesario establecer el relleno de ambos iconos. Aquí se muestran tanto el método de devolución de llamada como el de actualización:
private static void OnIconColorChanged(DependencyObject obj,
    DependencyPropertyChangedEventArgs args)
{
  // When the color changes, set the icon color
  PlayButton control = (PlayButton)obj;
  control.PlayIcon.Fill = control.IconColor;
  control.PauseIcon.Fill = control.IconColor;
}
Para completar el control, usted querrá también que un DependencyProperty permita asignar un MediaElement al control (consulte la Figura 11).
Ahora que tiene la propiedad, puede agregar un MediaElement a XAML y enlazar los datos de este elemento a la propiedad nueva de MediaPlayer. Al agregar el MediaElement a XAML, es necesario establecer el LoadedBehavior en el manual, lo que le permitirá controlar la reproducción manualmente. El XAML nuevo se muestra en la Figura 12.
<!-- MainWindow.xaml -->
<Window x:Class=”Tester.MainWindow”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:cust=”clr-namespace:CustomWPF;assembly=CustomWPF”
    Title=”Control Viewer” 
    Height=”100” Width=”200”>
  <StackPanel>

    <MediaElement Width=”150” Height=”100” 
         Name=”theMedia” 
         Source=”http://download.microsoft.com/.../ctorrec9billg.wmv”
         LoadedBehavior=”Manual” />

    <TextBlock>User Control:</TextBlock>

    <cust:PlayButton MediaPlayer=”{Binding ElementName=theMedia}” />

  </StackPanel>
</Window>
A continuación, implemente un evento de clic en el control de usuario de PlayButton. En primer lugar, agregue un evento MouseLeftButtonUp en la cuadrícula principal de control.
<!-- PlayButton.xaml --> 
<UserControl x:Class=”CustomWPF.PlayButton”    
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>
  <Grid MouseLeftButtonUp=”PlayButton_Clicked”>
    <!-- ... -->
  </Grid>
</UserControl>
Esto le permitirá implementar el comportamiento de su control y también cambiar el icono. Esta implementación de controlador de eventos se muestra en la Figura 13. El control y el vídeo completados se muestran en la Figura 14.
Figura 14 Control de usuario completado 
Controles personalizados
El control de PlayButton que acaba de crear funciona bastante bien, pero carece de compatibilidad con plantillas y temas. Si su control necesita esta compatibilidad, deberá generarlo como un control personalizado. Los controles personalizados derivan de otras clases en la jerarquía de controles. Por ejemplo, puede refactorizar el control de PlayButton en un control de MediaButton que sea más reutilizable.
Para crear un control de MediaButton, escoja primero control personalizado (WPF) en el diálogo Agregar nuevo elemento de Visual Studio. Se agregará un nuevo archivo de clase de control personalizado (MediaButton.cs) al proyecto y también una carpeta del tema con un archivo generic.xaml. El archivo generic.xaml contiene una plantilla para la nueva clase de control. Usa este archivo XAML para permitir diferentes temas para el control. El archivo generic.xaml se usa como reserva; para la mayoría de los controles éste es el único archivo de tema que se creará. Si quiere escribir un control que cambie su apariencia dependiendo del tema que se trate, puede crear los archivos del tema en este directorio. La figura 15 muestra los archivos estándar del tema y cuándo se usan.
Si se especifican varios temas puede cambiar la apariencia de sus controles según el tema que seleccione el usuario. Para desarrollar un tema genérico para el control de muestra, se puede tomar el archivo de control de usuario XAML y colocarlo dentro de la etiqueta ControlTemplate. Una vez que XAML esté en la plantilla, querrá usar enlaces de plantilla para establecer las propiedades de XAML basadas en propiedades del control. Hasta ahora, el ancho y la altura de PlayButton estaban establecidos a cincuenta unidades lógicas. Para obtener un control sencillo que sea coherente, pero también reutilizable, la plantilla debe ser redimensionable. Para ello, sustituya la altura y el ancho de la plantilla por la altura y el ancho del control marcándolos en la plantilla en {TemplateBinding Width} y {TemplateBinding Height}.
En el PlayButton, cambie simplemente la opacidad de los dos iconos dependiendo de si deben mostrar reproducción o pausa. Se puede obtener acceso a la plantilla para cambiar la opacidad, pero puede resultar bastante complejo. Una solución más óptima es tener un solo objeto de acceso a icono y cambiar los datos extraídos de manera que aparezca el icono correspondiente en cada caso. De este modo, el tamaño del árbol visual influye directamente en el rendimiento del documento XAML. Para ello, introduzca un nuevo DependencyProperty para almacenar el icono actual que se debe usar. Cree una enumeración que especifique qué icono usar, y entonces expóngala como un DependencyProperty. Con la nueva propiedad de icono puede modificar la plantilla para incluir desencadenadores para cuando ésta cambie.
El icono utiliza un elemento de ruta de acceso para definir la apariencia de cada icono que usa el botón. Esto funciona bien si el botón siempre tiene un tamaño fijo, pero como no es así, es necesario encontrar una forma de cambiar el tamaño del icono con el botón. Una solución es crear una elipse superpuesta al círculo de fondo y usar un VisualBrush para pintar el icono. El VisualBrush permite que el fondo se ajuste con el control. La plantilla generic.xaml completa se muestra en la Figura 16.
Este MediaButton debe controlar un elemento de medios como el que controlaba el PlayButton. Copie el MediaPlayer DependencyProperty del PlayButton al MediaButton. Asegúrese de cambiar cualquier referencia del código copiado del PlayButton a MediaButton (especialmente en el registro de DependencyProperty).
A diferencia de PlayButton, no es necesario controlar el evento de clic del mouse en la plantilla. En su lugar, puede invalidar el evento On­Mouse­Left­But­tonUp para reaccionar a los clics. Dentro de este método es posible cambiar el icono y reproducir o pausar el medio. El código final del control personalizado se puede consultar en la Figura 17. Ahora que el nuevo control admite el cambio del tamaño y la configuración de la propiedad del icono, se puede ofrecer más flexibilidad a los usuarios cambiando el tamaño y el icono del control. La figura 18 muestra el control con tamaños e iconos diferentes.
Figura 18 Todas las formas y tamaños  

En este ejemplo del control se ha derivado directamente de la clase System.Windows.Controls.Control, pero la naturaleza de controles personalizados permite derivar desde cualquier punto de la jerarquía de clases. Los controles personalizados se pueden usar para invalidar y cambiar el comportamiento de controles integrados o construir controles propios completamente desde cero. Por ejemplo, derivar de FrameworkElement le permite crear un control con muy poca mecánica de disposición integrada. La derivación del panel le permite crear sus propios contenedores especializados para otros objetos. No es fácil determinar la clase correcta de la que derivar, eso depende de los requisitos de su control.

Resumen
Cuando necesite una funcionalidad de control especializada, puede recurrir a varias opciones, entre ellas la composición, los estilos y las plantillas. Al usar la estructuración en distintos componentes se pueden crear controles compuestos sin la necesidad de crear un nuevo control. Si lo único que debe cambiarse es la apariencia de un control, use el estilo. Por último, las plantillas permiten un control completo de la composición de un control existente. Para obtener más información sobre el uso de las plantillas para personalizar controles, consulte la columna Foundations de Charles Petzold.
Cuando decida crear un nuevo control, obtendrá el modelo de programación simplificado que le dará la impresión de escribir en la propia ventana o página. Otra ventaja de los controles personalizados es que le permiten crear plantillas para sus controles que parecen y actúan de forma diferente en varios temas del sistema operativo.
La migración de un control de usuario existente a un control personalizado no es especialmente difícil, pero como se está trabajando con una plantilla, en vez del acceso directo a objetos de XAML, será necesario cambiar la forma de dirigir su control personalizado.
Con Windows Presentation Foundation, la necesidad de escribir controles personalizados se convierte en la excepción, más que la regla. Sólo cuando esté creando el comportamiento personalizado será necesario profundizar en la creación de controles. Para obtener más información sobre controles en Windows Presentation Foundation, consulte el SDK en msdn2.microsoft.com/ms754130.aspx.

Shawn Wildermuth es un MVP de Microsoft, MCSD.NET, MCT y el fundador de Wildermuth Consulting Services. Shawn es también el autor de Pragmatic ADO.NET (Addison-Wesley, 2002), y coautor de cuatro kits de aprendizaje de certificación Microsoft así como de la próxima arquitectura prescriptiva de datos. Puede ponerse en contacto con él a través de su sitio web www.wildermuthconsulting.com.

Page view tracker