具有这些类型限定名称的依赖属性称为附加依赖属性。它们的创建方式与常规依赖属性类似,但有以下区别:
应该通过调用 DependencyProperty.RegisterAttached() 来初始化 DependencyProperty 字段,而不是简单地调用 Register()。
-
因为属性值被“附加”到可能不知道该属性的对象上,所以通常不会创建 CLR 属性包装器。相反,创建一对静态 Get/Set 方法:
public static double GetWidth(DependencyObject target) { /* ... */ }
public static void SetWidth(DependencyObject target, double value) { /* ... */ }
有趣的是,XAML 解析器可以利用 不是 依赖属性的附加属性。只需要相关的静态 Get/Set 方法。
虽然核心 WPF 中一些最常见的用例是声明要分配给子元素的属性,例如,由 Panel 排列的元素,但这并不是唯一的用例。这个想法是,由任意类型声明的属性可用于在任何对象上设置值,即使它不知道该属性。这使得它们对Attached Behaviors 等有用。
在您的情况下,您似乎想要声明可以在样式或模板中引用的新布局相关属性。这也是一个常见的用例。示例:
public static class TitleBar {
public static readonly DependencyProperty WidthProperty =
DependencyProperty.RegisterAttached(
"Width",
typeof(double),
typeof(TitleBar),
new FrameworkPropertyMetadata(double.NaN));
public static double GetWidth(DependencyObject target) {
return (double)target.GetValue(TitleBarProperty);
}
public static void SetWidth(DependencyObject target, double value) {
target.SetValue(TitleBarProperty, value);
}
// TODO: Add similar members for additional properties...
}
如果您想鼓励仅在 Window 元素上设置属性,只需将 Get/Set 方法的第一个参数替换为 Window 而不是 DependencyObject。
应在何处声明属性取决于用例。如果属性仅对特定 UI 元素有意义(例如,Grid 将 Row 和 Column 声明为布局提示),则该元素应声明该属性。如果要在样式或模板中引用其他元数据,您可能应该在适当命名的静态类中声明它(如我上面的示例中所示)。如果要将其用作附加行为的一部分,则应在该行为的类中声明。
声明属性的类的名称是出现在 XAML 引用中 . 左侧的名称。在上面的 TitleBar 示例中,Width 属性在 XAML 中将被引用为 ns:TitleBar.Width,其中 ns 映射到包含 TitleBar 类的 CLR 命名空间。