wpf relativesource templatebinding

WPF TemplateBinding vs RelativeSource TemplatedParent



(7)

Pensé que TemplateBinding no admite tipos de Freezable (que incluye objetos de pincel). Para evitar el problema Uno puede hacer uso de TemplatedParent

¿Cuál es la diferencia entre estos 2 enlaces?

<ControlTemplate TargetType="{x:Type Button}"> <Border BorderBrush="{TemplateBinding Property=Background}"> <ContentPresenter /> </Border> </ControlTemplate>

y

<ControlTemplate TargetType="{x:Type Button}"> <Border BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}"> <ContentPresenter /> </Border> </ControlTemplate>

?


RelativeSource TemplatedParent

Este modo permite vincular una propiedad determinada de ControlTemplate a una propiedad del control al que se aplica ControlTemplate. Para entender bien el problema aquí hay un ejemplo abajo

<Window.Resources> <ControlTemplate x:Key="template"> <Canvas> <Canvas.RenderTransform> <RotateTransform Angle="20"/> </Canvas.RenderTransform> <Ellipse Height="100" Width="150" Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}"> </Ellipse> <ContentPresenter Margin="35" Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"/> </Canvas> </ControlTemplate> </Window.Resources> <Canvas Name="Parent0"> <Button Margin="50" Template="{StaticResource template}" Height="0" Canvas.Left="0" Canvas.Top="0" Width="0"> <TextBlock FontSize="22">Click me</TextBlock> </Button> </Canvas>

Si deseo aplicar las propiedades de un control dado a su plantilla de control, entonces puedo usar el modo TemplatedParent. También hay una similar a esta extensión de marcado que es el TemplateBinding que es una especie de mano corta del primero, pero el TemplateBinding se evalúa en tiempo de compilación en el contraste del TemplatedParent que se evalúa inmediatamente después del primer tiempo de ejecución. Como puede observar en la siguiente figura, el fondo y el contenido se aplican desde el botón a la plantilla de control.



TemplateBinding es una abreviatura de Binding with TemplatedParent pero no expone todas las capacidades de la clase Binding, por ejemplo, no puede controlar Binding.Mode from TemplateBinding.


TemplateBinding no es exactamente lo mismo. Los documentos de MSDN suelen ser escritos por personas que tienen que cuestionar los SDE monosilábicos sobre las características del software, por lo que los matices no son del todo correctos.

TemplateBindings se evalúan en tiempo de compilación contra el tipo especificado en la plantilla de control. Esto permite una instanciación mucho más rápida de plantillas compiladas. Solo busque el nombre en un enlace de plantilla y verá que el compilador lo marcará.

El marcado de enlace se resuelve en tiempo de ejecución. Aunque es más lento de ejecutar, el enlace resolverá los nombres de propiedad que no son visibles en el tipo declarado por la plantilla. Más lento, señalaré que es un tipo de pariente ya que la operación de enlace requiere muy poco de la CPU de la aplicación. Si estuvieras lanzando plantillas de control a gran velocidad, podrías notarlo.

Como práctica, utiliza TemplateBinding cuando puedas pero no temas el enlace.


Una cosa más: TemplateBindings no permite la conversión de valor. No le permiten pasar un convertidor y no convierten automáticamente int en cadena, por ejemplo (lo cual es normal para un enlace).


Vinculación de TemplateBinding : más limitado que el uso de enlaces regulares

  • Más eficiente que un enlace pero tiene menos funcionalidad
  • Solo funciona dentro del árbol visual de ControlTemplate
  • No funciona con propiedades en Freezables
  • No funciona dentro de un disparador de ControlTemplate
  • Proporciona un acceso directo a las propiedades de configuración (no tan detallado), por ejemplo, {TemplateBinding targetProperty}

Binding regular: no tiene las limitaciones anteriores de TemplateBinding

  • Respeta las propiedades de los padres
  • Restablece los valores objetivo para borrar cualquier valor explícitamente establecido
  • Ejemplo: <Ellipse Fill = "{Binding RelativeSource = {RelativeSource TemplatedParent}, Path = Background}" />