WPF TemplateBinding vs RelativeSource TemplatedParent

169

¿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>

?

PaN1C_Showt1Me
fuente
17
si necesita TwoWay Binding, debe usar la segunda opción
Joachim Kerschbaumer el

Respuestas:

207

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

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

El marcado vinculante se resuelve en tiempo de ejecución. Si bien 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 lentamente, señalaré que es un tipo de pariente ya que la operación de enlace toma muy poco de la CPU de la aplicación. Si estaba volando plantillas de control a gran velocidad, podría notarlo.

Como práctica, use TemplateBinding cuando pueda, pero no tema, a Binding.

Grant BlahaErath
fuente
18
Así que lo principal es recordar: Tiempo de compilación vs tiempo de ejecución. TemplateBinding no funcionará si intenta cambiarlo durante el tiempo de ejecución. Derecho ?
PaN1C_Showt1Me
3
También tenga en cuenta que el uso de Binding en lugar de TemplateBinding puede tener implicaciones en cuanto a lo que ve durante el tiempo de diseño. En ciertas configuraciones, las propiedades que están vinculadas usando {Binding RelativeSource ...} no aparecerán en el diseñador (aunque todavía se muestran durante el tiempo de ejecución), pero si cambia a usar {TemplateBinding ...} esas propiedades se evalúan durante el tiempo de diseño.
lfalin
Una cosa que agregaré en caso de que ayude a futuros visitantes es que debido a que TemplateBinding se evalúa en tiempo de compilación, no puede usar TemplateBinding para enlazar a una propiedad adjunta definida por el usuario. En el caso de propiedades adjuntas definidas por el usuario, debe utilizar "{Binding RelativeSource = {RelativeSource TemplatedParent} ...}"
MNB
35

Encuadernación de plantillas : más limitante que usar la encuadernación regular

  • 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 del activador de ControlTemplate
  • Proporciona un acceso directo en la configuración de propiedades (no como detallado), por ejemplo, {TemplateBinding targetProperty}

Enlace regular : no tiene las limitaciones anteriores de TemplateBinding

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

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

Miroslav Nedyalkov
fuente
1
Gracias Miroslav, este fue el problema que estaba encontrando, cambiar a usar TemplatedParent resolvió el problema.
MikeKulls
17

TemplateBinding es una forma abreviada de Binding con TemplatedParent, pero no expone todas las capacidades de la clase Binding, por ejemplo, no puede controlar Binding.Mode desde TemplateBinding.

Nir
fuente
1

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

Yaz
fuente