2010-11-08 37 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>