WPF TemplateBinding vs RelativeSource TemplatedParent


169

Sự khác biệt giữa 2 ràng buộc này là gì:

<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
nếu bạn cần TwoWay Binding, bạn phải sử dụng tùy chọn thứ hai
Joachim Kerschbaumer

Câu trả lời:


207

TemplateBinding không hoàn toàn giống nhau. Các tài liệu MSDN thường được viết bởi những người phải đánh đố các SDE đơn âm về các tính năng phần mềm, vì vậy các sắc thái không hoàn toàn đúng.

TemplateBindings được đánh giá tại thời điểm biên dịch so với loại được chỉ định trong mẫu điều khiển. Điều này cho phép khởi tạo nhanh hơn nhiều các mẫu được biên dịch. Chỉ cần tìm tên trong một liên kết mẫu và bạn sẽ thấy trình biên dịch sẽ gắn cờ nó.

Đánh dấu ràng buộc được giải quyết trong thời gian chạy. Trong khi thực thi chậm hơn, ràng buộc sẽ giải quyết các tên thuộc tính không hiển thị trên loại được khai báo bởi mẫu. Bằng cách chậm hơn, tôi sẽ chỉ ra rằng loại tương đối của nó vì hoạt động liên kết chiếm rất ít cpu của ứng dụng. Nếu bạn đang nổ mìn các mẫu điều khiển xung quanh với tốc độ cao, bạn có thể nhận thấy nó.

Vì vấn đề thực tế, hãy sử dụng TemplateBinding khi bạn có thể nhưng đừng sợ Binding.


18
Vì vậy, suy nghĩ chính cần nhớ: Biên dịch thời gian so với thời gian chạy. TemplateBinding sẽ không hoạt động nếu bạn cố gắng thay đổi trong thời gian chạy. Đúng ?
PaN1C_Showt1Me

3
Cũng lưu ý rằng việc sử dụng Binding thay vì TemplateBinding có thể có ý nghĩa như những gì bạn thấy trong Thời gian thiết kế. Trong một số cấu hình nhất định, các thuộc tính được ràng buộc bằng {Binding RelativeSource ...} sẽ không xuất hiện trong trình thiết kế (mặc dù chúng vẫn hiển thị trong thời gian chạy), nhưng nếu bạn chuyển sang sử dụng {TemplateBinding ...} thì các thuộc tính đó được đánh giá trong thời gian thiết kế.
lfalin

Một điều tôi sẽ thêm vào trong trường hợp nó giúp khách truy cập trong tương lai là bởi vì TemplateBinding được đánh giá tại thời điểm biên dịch, bạn không thể sử dụng TemplateBinding để liên kết với thuộc tính đính kèm do người dùng xác định. Trong trường hợp thuộc tính được đính kèm do người dùng xác định, bạn phải sử dụng "{Binding RelativeSource = {RelativeSource TemplatedParent} ...}"
MNB

35

TemplateBinding - Hạn chế hơn so với sử dụng Binding thông thường

  • Hiệu quả hơn Binding nhưng nó có ít chức năng hơn
  • Chỉ hoạt động bên trong cây trực quan của ControlTemplate
  • Không hoạt động với các thuộc tính trên Freezables
  • Không hoạt động trong Trình kích hoạt của ControlTemplate
  • Cung cấp một lối tắt trong các thuộc tính cài đặt (không phải là dài dòng), ví dụ {TemplateBinding targetProperty}

Binding thường xuyên - Không có giới hạn trên của TemplateBinding

  • Tôn trọng tài sản của phụ huynh
  • Đặt lại các giá trị mục tiêu để xóa mọi giá trị được đặt rõ ràng
  • Ví dụ: <Ellipse Fill = "{Binding RelativeSource = {RelativeSource TemplatedParent}, Path = Background}" />

22

Một điều nữa - TemplateBindings không cho phép chuyển đổi giá trị. Ví dụ, chúng không cho phép bạn chuyển Trình chuyển đổi và không tự động chuyển đổi int thành chuỗi (điều này là bình thường đối với Binding).


1
Cảm ơn Miroslav, đây là vấn đề tôi gặp phải, chuyển sang sử dụng TemplatedParent đã giải quyết vấn đề.
MikeKulls

17

TemplateBinding là một cách viết tắt của Binding with TemplatedParent nhưng nó không bộc lộ tất cả các khả năng của lớp Binding, ví dụ bạn không thể điều khiển Binding.Mode từ TemplateBinding.


1

Tôi nghĩ rằng TemplateBinding không hỗ trợ các loại Freezable (bao gồm các đối tượng cọ vẽ). Để giải quyết vấn đề. Người ta có thể sử dụng TemplatedParent


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.