2009-07-23 45 views
21

Tôi hơi băn khoăn về cách Thuộc tính được đính kèm thực sự truyền đạt giá trị của chúng cho các phần tử cha hoặc con. TextElement.FontFamily làm cho các phần tử con kế thừa giá trị được gán cho thuộc tính đó (một hoạt động dường như ở hạ lưu, từ cha mẹ sang con). Grid.Column làm cho một mục cha để hiển thị con đó ở một vị trí cụ thể (một hoạt động dường như ngược dòng, con với cha mẹ). Giá trị Thuộc tính được đính kèm biết luồng lưu lượng lên hoặc xuống như thế nào? Quan điểm của tôi về điều này là không chính xác, hay có một mảnh nào đó thiếu sót sẽ đưa tất cả điều này vào quan điểm?Chính xác các thuộc tính đính kèm hoạt động như thế nào trong WPF?

<StackPanel TextElement.FontFamily="Wingdings"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 

     <Button Grid.Column="1" Content="My Button"/> 
    </Grid> 
</StackPanel> 

Trả lời

38

Có hai khái niệm ở đây: thuộc tính phụ thuộcthuộc tính phụ thuộc đính kèm. "Thuộc tính được đính kèm" là các thuộc tính phụ thuộc và phụ thuộc hỗ trợ như vậy property value inheritance.

Về các thuộc tính phụ thuộc cơ bản, một tuyên bố rất thô sẽ là về cơ bản chúng kế thừa giá trị của chúng từ các phần tử cha trong cây wpf (hợp lý/hình ảnh). Thuộc tính phụ thuộc (được đính kèm hoặc không) kế thừa giá trị của nó "hướng xuống" nếu số metadata được đặt bằng FrameworkPropertyMetadataOptions. Thừa kế cờ và trong nhiều trường hợp, điều này là như vậy.

Thuộc tính được đính kèm là các thuộc tính có thể được đặt trên bất kỳ đối tượng wpf nào (về cơ bản, ít nhất một DependencyObject) thông qua phương thức DependencyObject.SetValue. Mục đích của cơ chế này là "đính kèm" vào các đối tượng khác thông tin cần thiết bởi các đối tượng cha mẹ, không phải chính các đối tượng con. Ví dụ, Grid.Row là thuộc tính đính kèm theo yêu cầu của lưới để đặt các mục trong vùng render của nó.

Thuộc tính phụ thuộc được kế thừa tự động "hướng xuống" bởi hệ thống đối tượng wpf.

Thuộc tính được đính kèm được kiểm tra "trở lên" một cách rõ ràng, trong mã của các đối tượng cụ thể. Trong trường hợp của Grid, khi xác định nơi để đặt các mục của nó, nó sẽ kiểm tra giá trị của Grid.Row và Grid.Column thuộc tính đính kèm trên mỗi mục chứa.

Nó cũng thường là kỹ thuật tạo thuộc tính được đính kèm tùy chỉnh mà sửa đổi theo cách nào đó mà các đối tượng được gắn vào (ví dụ: Drag'n'Drop functionality via attached properties).

Là một lưu ý bổ sung, ví dụ hay về thuộc tính được kế thừa đính kèm là TextElement.FontFamily. Thuộc tính Grid.Row và Grid.Column không có bộ cờ Inherits.

TextElement.FontFamily, từ Reflector:

FontFamilyProperty = DependencyProperty.RegisterAttached("FontFamily", typeof(FontFamily), typeof(TextElement), new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily, FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(TextElement.IsValidFontFamily)); 

Grid.Row, từ Reflector:

RowProperty = DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid), new FrameworkPropertyMetadata(0, new PropertyChangedCallback(Grid.OnCellAttachedPropertyChanged)), new ValidateValueCallback(Grid.IsIntValueNotNegative)); 
+1

Thú vị và mang tính thông tin. Điều gì về kịch bản này, mặc dù: Một lưới 2x2 (A) chứa một lưới 2x2 (B). Lưới B chứa một Nút. Nếu Grid B có Grid của nó.Thuộc tính Cột đính kèm được đặt thành 1 (vì vậy nó xuất hiện trong cột thứ hai của lưới cha của nó, Lưới A), không nên Thuộc tính đính kèm xếp xuống dưới nút Lưới B, do đó nút xuất hiện trong cột thứ hai của lưới B? – Pwninstein

+1

Câu hỏi hay, thêm thông tin vào câu trả lời. –

+0

Tuyệt vời! Làm cho nhiều ý nghĩa hơn bây giờ, cảm ơn !! – Pwninstein

2

Từ MSDN:

Mặc dù tài sản gắn liền là settable trên bất kỳ đối tượng, điều đó không tự động có nghĩa là thiết lập tài sản sẽ tạo ra một kết quả hữu hình, hoặc là giá trị sẽ bao giờ được sử dụng bởi một đối tượng khác. Nói chung, các thuộc tính đính kèm được dự định để các đối tượng đến từ nhiều phân cấp lớp có thể hoặc các mối quan hệ hợp lý có thể báo cáo thông tin chung cho loại xác định thuộc tính đính kèm. Các loại định nghĩa các tài sản gắn liền thường sau một trong những mô hình:

  • kiểu định nghĩa gắn liền bất động sản được thiết kế để nó có thể là yếu tố phụ huynh trong những yếu tố rằng sẽ thiết lập giá trị cho các đính kèm tài sản. Loại sau đó lặp lại các đối tượng con của nó thông qua logic nội bộ đối với một số cấu trúc cây đối tượng, lấy giá trị và hành động theo các giá trị theo một cách nào đó.

  • Loại xác định thuộc tính được đính kèm sẽ được sử dụng làm phần tử con cho nhiều loại khác nhau có thể các phần tử và mô hình nội dung chính.

  • Loại xác định thuộc tính được đính kèm đại diện cho dịch vụ. Các loại khác đặt giá trị cho thuộc tính đính kèm. Sau đó, khi phần tử đặt thuộc tính được đánh giá trong ngữ cảnh của dịch vụ, giá trị thuộc tính được đính kèm thu được thông qua logic nội bộ của lớp dịch vụ.

Một thí dụ về một Parent-Defined đính kèm tài sản

Kịch bản tiêu biểu nhất nơi WPF định nghĩa một tài sản gắn liền là khi một yếu tố phụ huynh hỗ trợ một bộ sưu tập phần tử con, và cũng có thể thực hiện một hành vi nơi chi tiết cụ thể của hành vi được báo cáo riêng cho từng phần tử con.

DockPanel xác định thuộc tính được gắn DockPanel.Dock và DockPanel có mã cấp lớp như một phần của logic hiển thị của nó (cụ thể là MeasureOverride và ArrangeOverride). Một cá thể DockPanel sẽ luôn kiểm tra xem liệu bất kỳ phần tử con trực tiếp nào của nó có đặt giá trị cho DockPanel.Dock hay không. Nếu vậy, các giá trị đó trở thành đầu vào cho logic kết xuất được áp dụng cho phần tử con cụ thể đó. Các trường hợp DockPanel lồng nhau từng xử lý các bộ sưu tập phần tử con ngay lập tức của riêng chúng, nhưng hành vi đó là thực hiện cụ thể cho cách DockPanel xử lý các giá trị DockPanel.Dock. Về lý thuyết, về mặt lý thuyết có thể có các thuộc tính kèm theo ảnh hưởng đến các phần tử ngoài cha mẹ trực tiếp. Nếu DockPanel.Dock đính kèm tài sản được thiết lập trên một yếu tố mà không có yếu tố phụ huynh DockPanel để hành động theo nó, không có lỗi hoặc ngoại lệ được nâng lên. Điều này đơn giản có nghĩa là một giá trị thuộc tính toàn cục được thiết lập, nhưng nó không có cha mẹ DockPanel hiện tại có thể tiêu thụ thông tin.

0

Nói cách đơn giản đây là cách tôi hiểu nó (hãy sửa lại cho tôi nếu tôi sai).

Một đối tượng (A) thực hiện một thuộc tính sẽ gắn với đối tượng khác (B) (đối tượng B thậm chí không biết về sự tồn tại của thuộc tính "có thể đính kèm" này). Đối tượng B cần kế thừa từ DependencyObject.

Đối tượng A cũng thực hiện một phương pháp tĩnh để kiểm tra thuộc tính "có thể đính kèm" của nó trong các đối tượng khác, A.GetAttachedProperty (B).

Nếu B có thuộc tính đính kèm từ A, A.GetAttachedProperty sẽ đọc và trả về giá trị của nó. Nếu không A sẽ cố gắng đọc nó và trả về null vì nó không có ở đó.

Các vấn đề liên quan