2010-11-08 44 views
1

附加屬性如何通過擁有父元素定義的單個屬性通過該父級的多個子元素設置多個值?AttachedProperty如何具有多個值?

例如:

如果我有:

<DockPanel> 
    <CheckBox DockPanel.Dock="Top">Hello</CheckBox> 
    <CheckBox DockPanel.Dock="Bottom">World</CheckBox> 
</DockPanel> 

在這裏,我們有一個DockPanel中元素,它有一個單一的Dock屬性。它怎麼可以同時設置爲「頂部」和「底部」?

回答

3

它會在一個方法結束這樣看

public class DockPanel : Panel 
{ 
    public static readonly DependencyProperty DockProperty; 
    // ... 
    public static void SetDock(UIElement element, Dock dock) 
    { 
     element.SetValue(DockProperty, value); 
    } 
} 

正如你所看到的,它實際上沒有設置父,但複選框本身,通過對DockPanel中的靜態方法SetDock而不是父母實例。在後面的代碼中做這件事使得這個更清晰一些,注意我們從來沒有使用DockPanel的實例。

DockPanel.SetDock(checkBox1, Dock.Top); 
DockPanel.SetDock(checkBox2, Dock.Bottom); 

希望這是明確的,除非你的問題是這是如何工作「引擎蓋下」。在這種情況下,請參閱this問題。

來自鏈接的報價。

的宗旨,爲這一機制是 「附加」到其他對象的父對象所需的信息 ,而不是 子對象本身。

CheckBox對Dock屬性沒有用處,除非它在DockPanel中。 Grid.Row,Canvas.Left,Validation.HasError(只讀)等也是如此。所以基本上,DockPanel是需要信息的那個,但它需要所有的孩子才能存儲它。因此,它使用附加屬性。如果您創建了一個名爲PuneetPanel的新面板,並且您需要一位天使來計算孩子的位置,那麼您可以在此面板中定義您自己的附加屬性PuneetPanel.Angel,並且所有孩子都可以使用此面板,而不必進行子類別劃分。

+0

所以,我不明白什麼是「AttachedProperty」的用法,它是做什麼的,當CheckBox最終與CheckBox一起存儲時,也可以使用CheckBox上的某些屬性來完成。爲什麼DockPanel正在定義和擁有該屬性並使用它來維護屬性標識符。 – teenup 2010-11-08 07:15:09

0

這是一個非常好的問題。答案在於AttchedProperty的工作原理。父母使用AttachedProperty來呈現孩子。在呈現子對象之前,父對象將查找在子對象上定義的任何附加屬性,並將其應用於子對象。

我發現這個從MSDN這可能是你::

DockPanel中定義DockPanel.Dock附加屬性,和具有DockPanel中的類級碼作爲它的渲染邏輯的一部分(具體而言,的MeasureOverride和有用ArrangeOverride)。
DockPanel實例將一直檢查是否有任何直接子元素爲DockPanel.Dock設置了一個值。如果是這樣,這些值將成爲適用於特定的子元素,呈現邏輯輸入....

你可以看到這個鏈接以獲得詳細的概述::
http://http://msdn.microsoft.com/en-us/library/ms749011.aspx

希望它可以幫助你!

+0

我已經閱讀過這個msdn頁面,從閱讀本頁面,我有這個疑問。我知道父母會查詢孩子的那個屬性,但是在哪個對象中,屬性的不同值將被保存?因爲屬性是擁有類中的單個成員變量,並且一次只能有一個值。我猜想這個屬性將在這個例子中分開存儲在兩個複選框中,但是CheckBox本身沒有任何Dock屬性。 – teenup 2010-11-08 05:09:10

+0

是附加屬性一次只能有一個DependencyObject(CheckBox)實例的單個值。它不會直接存儲在對象中。 WPF引擎在內部維護一個查找表,其中每個對象實例都與已設置的附加屬性相關。當您使用XAML或get accessor方法獲取值時,您可以使WPF查找表中的值。從外部*看起來*就好像你從對象直接檢索。 – bitbonk 2010-11-08 19:28:00

0

爲了達到你所尋找的自己定製的附加屬性有兩種選擇:

如果設定值的組合的數量並不複雜,你可以做類型的附加屬性列舉了FlagsAttribute。您可以在結合了值,您要使用設置按位或|

[Flags] 
public enum MultiDock 
{ 
    Left, 
    Top, 
    Right, 
    Bottom 
} 

及其代碼的用法:

MyCustomPanelOrWhatever.SetMultiDock(MultiDock.Left | MultiDock.Bottom); 

這有一個小proplem但是,你不能在上面做xaml直接,你將不得不寫一個MarkupExtension可以將字符串轉換爲標記的枚舉值。然後它的使用是這樣的:

<CheckBox src:MyCustomPanelOrWhatever.MulitDock="{src:FlaggedEnum Left|Bottom}" /> 

2.由於附加屬性可以是任何類型的,他們可以當然也可以是複雜的類型(具有多個子屬性)或甚至集合,因此可以容易地做這樣的事情:

MyCustomPanelOrWhatever.SetMultiDock(new List<MultiDock> { MultiDock.Left, MultiDock.Bottom }); 

如果您已經定義了附加屬性這樣,你不需要對任何XAML轉換器,你可以直接使用它:

<CheckBox> 
    <src:MyCustomPanelOrWhatever.MultiDock> 
     <src:MultiDock.Left/> 
     <src:MultiDock.Bottom/> 
    </src:MyCustomPanelOrWhatever.MultiDock> 
</CheckBox>