1

作为由拥有的父元素定义的单个属性的AttachedProperty如何通过该父元素的多个子元素设置多个值?

例如:

如果我有:

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

这里我们有一个 DockPanel 元素,它有一个 Dock 属性。如何将其设置为“顶部”,然后同时设置为“底部”?

4

3 回答 3

3

它最终会变成一个看起来像这样的方法

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

如您所见,它实际上不是设置在父级上,而是 CheckBox 本身,通过 DockPanel 上的静态方法 SetDock 而不是父级实例。在后面的代码中做这件事会更清楚一点,注意我们从不使用 DockPanel 的实例。

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

希望这很清楚,除非您的问题是它是如何“在引擎盖下”工作的。在这种情况下,请参阅问题。

从链接引用。

这种机制的目的是“附加”到父对象所需的其他对象信息,而不是子对象本身。

CheckBox 对 Dock 属性没有用处,除非它位于 DockPanel 中。Grid.Row、Canvas.Left、Validation.HasError(只读)等也是如此。所以基本上,DockPanel 是需要信息的,但它需要它的所有子级能够存储它。因此,它使用附加属性。如果您创建了一个名为 PuneetPanel 的新面板,并且您需要一个 Angel 来计算孩子的位置,那么您可以在此面板中定义自己的附加属性 PuneetPanel.Angel,并且所有孩子都可以使用它而无需子类化。

于 2010-11-08T07:04:45.420 回答
0

对于您自己的自定义附加属性,有两个选项可以实现您正在寻找的内容:

1.如果可设置值的组合数量不复杂,您可以将附加属性设置为具有FlagsAttribute集的枚举类型。您可以使用按位或组合要设置的值|

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

及其在代码中的用法:

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

不过,这有一个小问题,您不能直接在 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>
于 2010-11-08T08:08:44.510 回答
0

这是一个非常好的问题。答案在于 AttchedProperty 是如何工作的。父级使用 AttachedProperty 来渲染子级。在渲染孩子之前,父母会寻找在孩子上定义的任何附加属性并应用于孩子。

我从 msdn 找到了这个,它可能对你有用::

DockPanel 定义了 DockPanel.Dock 附加属性,并且 DockPanel 具有类级代码作为其呈现逻辑的一部分(特别是 MeasureOverride 和 ArrangeOverride)。
DockPanel 实例将始终检查其任何直接子元素是否为 DockPanel.Dock 设置了值。如果是这样,这些值将成为应用于该特定子元素的呈现逻辑的输入......

您可以查看此链接以获取详细概述 ::
http://msdn.microsoft.com/en-us/library/ms749011.aspx

希望对你有帮助!!

于 2010-11-08T04:57:21.140 回答