แม่แบบ WPF เทียบกับ RelativeSource TemplatedParent


169

อะไรคือความแตกต่างระหว่างการโยง 2 อันนี้:

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

และ

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

?


17
หากคุณต้องการเข้าร่วม TwoWay คุณต้องใช้ตัวเลือกที่สอง
Joachim Kerschbaumer

คำตอบ:


207

TemplateBinding ไม่ใช่สิ่งเดียวกัน เอกสาร MSDN นั้นมักเขียนโดยผู้ที่ต้องตอบคำถาม SDE ที่มีพยางค์เดียวเกี่ยวกับคุณสมบัติของซอฟต์แวร์ดังนั้นความแตกต่างจึงไม่ถูกต้องนัก

TemplateBindings ได้รับการประเมิน ณ เวลารวบรวมกับประเภทที่ระบุในเทมเพลตควบคุม สิ่งนี้ช่วยให้อินสแตนซ์ของแม่แบบที่คอมไพล์ได้เร็วขึ้นมาก เพียงคลำหาชื่อในการผูกแม่แบบและคุณจะเห็นว่าคอมไพเลอร์จะตั้งค่าสถานะ

มาร์กอัปการเชื่อมโยงได้รับการแก้ไขในขณะทำงาน ในขณะที่ช้าลงในการดำเนินการการผูกจะแก้ไขชื่อคุณสมบัติที่มองไม่เห็นในประเภทที่ประกาศโดยแม่แบบ โดยช้าฉันจะชี้ให้เห็นว่าชนิดของญาติเนื่องจากการดำเนินการผูกพันใช้ CPU น้อยมากของโปรแกรม หากคุณกำลังทำลายแม่แบบการควบคุมด้วยความเร็วสูงคุณอาจสังเกตเห็น

ตามหลักปฏิบัติแล้วใช้ TemplateBinding เมื่อคุณทำได้ แต่ไม่ต้องกลัวการผูกมัด


18
หลักคิดว่าควรจำ: รวบรวมเวลา vs Runtime TemplateBinding จะไม่ทำงานหากคุณพยายามที่จะเปลี่ยนระหว่างรันไทม์ ใช่มั้ย
PaN1C_Showt1Me

3
นอกจากนี้โปรดทราบว่าการใช้การผูกแทนการผูกแม่แบบอาจมีผลกระทบต่อสิ่งที่คุณเห็นในช่วงเวลาการออกแบบ ในการกำหนดค่าบางอย่างคุณสมบัติที่ถูกผูกไว้โดยใช้ {Binding RelativeSource ... } จะไม่ปรากฏในตัวออกแบบ (แม้ว่าพวกเขาจะยังคงปรากฏขึ้นในช่วงเวลาทำงาน) แต่ถ้าคุณสลับไปใช้การใช้ {TemplateBinding ... } คุณสมบัติเหล่านั้นจะถูกประเมิน ในช่วงเวลาการออกแบบ
lfalin

สิ่งหนึ่งที่ฉันจะเพิ่มในกรณีที่ช่วยผู้เยี่ยมชมในอนาคตก็คือเนื่องจากมีการประเมิน TemplateBinding ณ เวลารวบรวมคุณไม่สามารถใช้ TemplateBinding เพื่อเชื่อมโยงกับคุณสมบัติที่แนบมาของผู้ใช้ ในกรณีของคุณสมบัติที่แนบมาที่ผู้ใช้กำหนดคุณต้องใช้ "{Binding RelativeSource = {RelativeSource TemplatedParent} ... }"
MNB

35

TemplateBinding - การ จำกัด มากกว่าการใช้การผูกปกติ

  • มีประสิทธิภาพมากกว่าการผูก แต่ก็มีฟังก์ชั่นน้อยกว่า
  • ใช้งานได้เฉพาะภายในแผนภูมิภาพที่แสดงของ ControlTemplate
  • ไม่ทำงานกับคุณสมบัติใน Freezables
  • ไม่ทำงานภายในทริกเกอร์ของ ControlTemplate
  • ให้ทางลัดในการตั้งค่าคุณสมบัติ (ไม่ใช่ verbose) เช่น {TemplateBinding targetProperty}

การผูกปกติ- ไม่มีข้อ จำกัด เหนือ TemplateBinding

  • เคารพคุณสมบัติของผู้ปกครอง
  • รีเซ็ตค่าเป้าหมายเพื่อล้างค่าที่ตั้งไว้อย่างชัดเจน
  • ตัวอย่าง: <Ellipse Fill = "{Binding RelativeSource = {RelativeSource TemplatedParent}, Path = Background}" />

22

อีกสิ่งหนึ่ง - TemplateBindings ไม่อนุญาตการแปลงค่า พวกเขาไม่อนุญาตให้คุณผ่านตัวแปลงและไม่แปลง int เป็นสตริงโดยอัตโนมัติ (ซึ่งเป็นเรื่องปกติสำหรับการผูก)


1
ขอบคุณ Miroslav นี่เป็นปัญหาที่ฉันพบเจอการเปลี่ยนไปใช้ TemplatedParent แก้ปัญหาได้
MikeKulls

17

TemplateBinding เป็นชวเลขสำหรับ Binding with TemplatedParent แต่ไม่เปิดเผยความสามารถทั้งหมดของคลาส Binding ตัวอย่างเช่นคุณไม่สามารถควบคุม Binding.Mode จาก TemplateBinding


1

ฉันคิดว่า TemplateBinding ไม่สนับสนุนประเภท Freezable (ซึ่งรวมถึงวัตถุแปรง) เพื่อแก้ไขปัญหา หนึ่งสามารถใช้ TemplatedParent


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.