Clases de configuración de plantillas

Requisitos previos

Damos por hecho que sabes agregar controles a la interfaz de usuario, establecer sus propiedades y adjuntar controladores de eventos. Para obtener instrucciones para agregar controles a la aplicación, consulta Agregar controles y administrar eventos. También damos por hecho que conoces los conceptos básicos de cómo definir una plantilla personalizada para un control al realizar una copia de la plantilla predeterminada y modificarla. Para obtener más información al respecto, consulta Inicio rápido: plantillas de control.

Escenario para las clases TemplateSettings

Las clases TemplateSettings proporcionan un conjunto de propiedades que se usan al definir una nueva plantilla de control para un control. Las propiedades tienen valores como medidas de píxel para el tamaño de determinadas partes de los elementos de la interfaz de usuario. A veces, los valores son valores calculados que provienen de la lógica de control que normalmente no es de fácil reemplazo ni acceso. Algunas de las propiedades están pensadas como valores De origen y De destino que controlan las transiciones y animaciones de los elementos y, por ende, las propiedades TemplateSettings correspondientes vienen en pares.

Existen varias clases TemplateSettings. Todas ellas están en el espacio de nombres Windows.UI.Xaml.Controls.Primitives. A continuación, se ofrece una lista de las clases y un vínculo a la propiedad TemplateSettings del control correspondiente. Esta propiedad TemplateSettings define el modo de acceso a los valores TemplateSettings para el control y puede establecer enlaces de plantilla a sus propiedades:

Las propiedades TemplateSettings están pensadas para usarlas siempre en XAML, no para el código. Se trata de subpropiedades de solo lectura de una propiedad TemplateSettings de solo lectura de un control principal. Para un escenario avanzado de control personalizado, en el que creas una nueva clase basada en Control que, por consiguiente, puede influir en la lógica de control, considera la posibilidad de definir una propiedad TemplateSettings personalizada en el control para comunicar información que podría resultar útil a cualquier persona que esté volviendo a generar plantillas del control. Dado que esa propiedad es un valor de solo lectura, define una nueva clase TemplateSettings relacionada con tu control que tiene propiedades de solo lectura para cada uno de los elementos de información que son relevantes para las medidas de plantilla, posicionamiento de animación, etc. y asigna a los llamadores la instancia en tiempo de ejecución de la clase que se inicializa con la lógica de control. Las clases TemplateSettings se derivan de DependencyObject, de modo que las propiedades pueden usar el sistema de propiedades de dependencia de devoluciones de llamada de cambio de propiedad. Pero los identificadores de propiedades de dependencia para las propiedades no se exponen como API pública, porque las propiedades TemplateSettings deben ser de solo lectura para los llamadores.

Cómo usar TemplateSettings en una plantilla de control

Este es un ejemplo proveniente de las plantillas predeterminadas iniciales de control XAML. Este ejemplo en particular proviene de la plantilla predeterminada de ProgressRing:

<Ellipse
    x:Name="E1"
    Style="{StaticResource ProgressRingEllipseStyle}"
    Width="{Binding RelativeSource={RelativeSource TemplatedParent}, 
        Path=TemplateSettings.EllipseDiameter}"
    Height="{Binding RelativeSource={RelativeSource TemplatedParent}, 
        Path=TemplateSettings.EllipseDiameter}"
    Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, 
        Path=TemplateSettings.EllipseOffset}"
    Fill="{TemplateBinding Foreground}"/>

El código XAML completo para la plantilla ProgressRing contiene cientos de líneas, por lo que aquí se muestra un pequeño fragmento. Este código XAML define un elemento de control que es uno de los seis elementos Elipse que revelan la animación de giro de progreso indeterminado. Como desarrollador, quizá no quieras los círculos y podrías usar otra primitiva gráfica u otra una forma básica para el modo de avance de la animación. Por ejemplo, puedes componer un ProgressRing que use un conjunto de elementos Rectángulo organizados en un cuadrado. Si así fuera, cada componente de Rectángulo de la nueva plantilla podrían tener el aspecto siguiente:

<Rectangle
    x:Name="R1"
    Width="{Binding RelativeSource={RelativeSource TemplatedParent}, 
        Path=TemplateSettings.EllipseDiameter}"
    Height="{Binding RelativeSource={RelativeSource TemplatedParent}, 
        Path=TemplateSettings.EllipseDiameter}"
    Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, 
        Path=TemplateSettings.EllipseOffset}"
    Fill="{TemplateBinding Foreground}"/>

El motivo por el cual las propiedades TemplateSettings son útiles aquí es porque son valores calculados procedentes de la lógica de control básico de ProgressRing. El cálculo se realiza al dividir los valores ActualWidth y ActualHeight generales de ProgressRing y al asignar una medida calculada a cada uno de los elementos de movimiento en sus plantillas para que los elementos de plantilla puedan cambiar el tamaño según el contenido.

Este es otro ejemplo de uso de plantillas predeterminadas de control XAML. Esta vez el ejemplo muestra uno de los conjuntos de propiedades que corresponden a los valores De origen y De destino de una animación. Se trata de la plantilla predeterminada ComboBox:

<VisualStateGroup x:Name="DropDownStates">
    <VisualState x:Name="Opened">
        <Storyboard>
            <SplitOpenThemeAnimation
               OpenedTargetName="PopupBorder"
               ContentTargetName="ScrollViewer"
               ClosedTargetName="ContentPresenter"
               ContentTranslationOffset="0"
               OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                 Path=TemplateSettings.DropDownOffset}"
               OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                 Path=TemplateSettings.DropDownOpenedHeight}"
               ClosedLength="{Binding RelativeSource={RelativeSource TemplatedParent},
                 Path=TemplateSettings.DropDownClosedHeight}" />
        </Storyboard>
   </VisualState>
...
</VisualStateGroup>

Una vez más, hay gran cantidad de XAML en la plantilla, por lo que solo mostramos un fragmento. Además, este es solo uno de los diversos estados y animaciones de tema que usan las mismas propiedades ComboBoxTemplateSettings. En el caso de ComboBox, el uso de los valores ComboBoxTemplateSettings mediante enlaces exige que las animaciones relacionadas de la plantilla se detengan y se inicien en posiciones basadas en valores compartidos y, por consiguiente, la transición se realiza sin problemas.

Nota Al usar valores TemplateSettings como parte de la plantilla de control, asegúrese de que establece propiedades que coincidan con el tipo del valor. De lo contrario, tendrías que crear un convertidor de valores para el enlace para poder convertir el tipo de destino del enlace a partir de un tipo de origen diferente del valor TemplateSettings. Para obtener más información, consulta IValueConverter.