为何使用附加属性(摘自MSDN)
附加属性的一个用途是允许不同的子元素为实际在父元素中定义的属性指定唯一值。 此方案的一个具体应用是让子元素通知父元素它们将如何在用户界面 (UI) 中呈现。 一个示例是 DockPanel.Dock 属性。 DockPanel.Dock 属性创建为一个附加属性,因为它设计为在 DockPanel 中包含的元素上设置,而不是在 DockPanel 本身上设置。 DockPanel 类定义名为 DockProperty 的静态 DependencyProperty 字段,然后将 GetDock 和 SetDock 方法作为该附加属性的公共访问器提供。
如何创建附加属性 (摘自MSDN)
如果您的类将附加属性严格定义为用于其他类型,那么该类不必从 DependencyObject 派生。 但是,如果您遵循总体 WPF 模型具有该附加属性也是依赖项属性,但是,需要从 DependencyObject 派生。
通过声明一个 DependencyProperty 类型的 public static readonly 字段可以将附加属性定义为依赖项属性。通过使用 RegisterAttached 方法的返回值来定义此字段。 为了遵循命名标识字段及其所表示的属性的已建立 WPF 模式,字段名必须与附加属性名一致,并附加字符串 Property。 附加属性提供程序还必须提供静态 GetPropertyName 和 SetPropertyName 方法作为访问器为附加属性;否则会导致属性系统无法使用附加属性。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; namespace PropertyDemo { public static class PasswordBoxHelper { public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordBoxHelper), new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged)); public static readonly DependencyProperty AttachProperty = DependencyProperty.RegisterAttached("Attach", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, Attach)); private static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), typeof(PasswordBoxHelper)); public static void SetAttach(DependencyObject dp, bool value) { dp.SetValue(AttachProperty, value); } public static bool GetAttach(DependencyObject dp) { return (bool)dp.GetValue(AttachProperty); } public static string GetPassword(DependencyObject dp) { return (string)dp.GetValue(PasswordProperty); } public static void SetPassword(DependencyObject dp, string value) { dp.SetValue(PasswordProperty, value); } private static bool GetIsUpdating(DependencyObject dp) { return (bool)dp.GetValue(IsUpdatingProperty); } private static void SetIsUpdating(DependencyObject dp, bool value) { dp.SetValue(IsUpdatingProperty, value); } private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; passwordBox.PasswordChanged -= PasswordChanged; if (!(bool)GetIsUpdating(passwordBox)) { passwordBox.Password = (string)e.NewValue; } passwordBox.PasswordChanged += PasswordChanged; } private static void Attach(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; if (passwordBox == null) return; if ((bool)e.OldValue) { passwordBox.PasswordChanged -= PasswordChanged; } if ((bool)e.NewValue) { passwordBox.PasswordChanged += PasswordChanged; } } private static void PasswordChanged(object sender, RoutedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; SetIsUpdating(passwordBox, true); SetPassword(passwordBox, passwordBox.Password); SetIsUpdating(passwordBox, false); } } }