WPF TemplateBinding vs RelativeSource TemplatedParent

169

Was ist der Unterschied zwischen diesen beiden Bindungen:

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

und

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

?

PaN1C_Showt1Me
quelle
17
Wenn Sie TwoWay Binding benötigen, müssen Sie die zweite Option verwenden
Joachim Kerschbaumer

Antworten:

207

TemplateBinding ist nicht ganz dasselbe. MSDN-Dokumente werden häufig von Personen geschrieben, die einsilbige SDEs zu Softwarefunktionen testen müssen, sodass die Nuancen nicht ganz richtig sind.

TemplateBindings werden zur Kompilierungszeit anhand des in der Steuerungsvorlage angegebenen Typs ausgewertet. Dies ermöglicht eine viel schnellere Instanziierung kompilierter Vorlagen. Fummeln Sie einfach den Namen in einer Vorlagenbindung und Sie werden sehen, dass der Compiler ihn markiert.

Das Bindungsmarkup wird zur Laufzeit aufgelöst. Während die Ausführung langsamer ist, werden durch die Bindung Eigenschaftsnamen aufgelöst, die für den von der Vorlage deklarierten Typ nicht sichtbar sind. Mit langsamer werde ich darauf hinweisen, dass es sich um einen Verwandten handelt, da der Bindungsvorgang nur sehr wenig von der CPU der Anwendung beansprucht. Wenn Sie Steuerungsvorlagen mit hoher Geschwindigkeit herumsprengen, werden Sie es möglicherweise bemerken.

Verwenden Sie die TemplateBinding aus praktischen Gründen, wenn Sie die Bindung nicht fürchten können.

Grant BlahaErath
quelle
18
Das Wichtigste, an das Sie sich erinnern sollten: Kompilierungszeit gegen Laufzeit. Die TemplateBinding funktioniert nicht, wenn Sie versuchen, sie zur Laufzeit zu ändern. Richtig ?
PaN1C_Showt1Me
3
Beachten Sie auch, dass die Verwendung von Bindung anstelle von TemplateBinding Auswirkungen auf das haben kann, was Sie während der Entwurfszeit sehen. In bestimmten Konfigurationen werden Eigenschaften, die mit {Binding RelativeSource ...} gebunden sind, nicht im Designer angezeigt (obwohl sie zur Laufzeit noch angezeigt werden). Wenn Sie jedoch zur Verwendung von {TemplateBinding ...} wechseln, werden diese Eigenschaften ausgewertet während der Entwurfszeit.
lfalin
Eine Sache, die ich hinzufügen werde, falls es zukünftigen Besuchern hilft, ist, dass Sie TemplateBinding nicht zum Binden an eine benutzerdefinierte angehängte Eigenschaft verwenden können, da TemplateBinding zur Kompilierungszeit ausgewertet wird. Bei benutzerdefinierten angehängten Eigenschaften müssen Sie "{Binding RelativeSource = {RelativeSource TemplatedParent} ...}"
MNB
35

TemplateBinding - Einschränkender als die Verwendung der regulären Bindung

  • Effizienter als eine Bindung, aber weniger Funktionalität
  • Funktioniert nur innerhalb des visuellen Baums einer ControlTemplate
  • Funktioniert nicht mit Eigenschaften von Freezables
  • Funktioniert nicht im Trigger einer ControlTemplate
  • Bietet eine Verknüpfung zum Festlegen von Eigenschaften (nicht so ausführlich), z. B. {TemplateBinding targetProperty}

Regelmäßige Bindung - Hat keine der oben genannten Einschränkungen für TemplateBinding

  • Respektiert die übergeordneten Eigenschaften
  • Setzt die Zielwerte zurück, um alle explizit festgelegten Werte zu löschen
  • Beispiel: <Ellipse Fill = "{Binding RelativeSource = {RelativeSource TemplatedParent}, Path = Background}" />
Paul Fischer
quelle
22

Noch etwas - TemplateBindings erlauben keine Wertkonvertierung. Sie erlauben Ihnen nicht, einen Konverter zu übergeben und konvertieren beispielsweise nicht automatisch int in einen String (was für eine Bindung normal ist).

Miroslav Nedyalkov
quelle
1
Dank Miroslav war dies das Problem, auf das ich gestoßen bin. Durch die Umstellung auf TemplatedParent wurde das Problem gelöst.
MikeKulls
17

TemplateBinding ist eine Abkürzung für Binding with TemplatedParent, stellt jedoch nicht alle Funktionen der Binding-Klasse zur Verfügung. Beispielsweise können Sie Binding.Mode nicht über TemplateBinding steuern.

Nir
quelle
1

Ich dachte, TemplateBinding unterstützt keine Freezable-Typen (einschließlich Pinselobjekte). Um das Problem zu umgehen. Man kann TemplatedParent verwenden

Yaz
quelle