依赖属性 附加属性通俗理解
依赖属性以及附加属性
依赖属性(DependencyProperty)
1.概念
依赖属性是一种可以自己没有值,并能通过使用Binding从数据源获得值的属性(通俗的讲,就是依赖在别的属性上)。
依赖属性是为了解决普通属性因继承而带来的对象膨胀。
例如Button的继承
Button->ButtonBase->ContentControl->Control->FrameworkElement->UIElement->Visual->DependencyObject->...
所以每次继承,父类的私有字段都会被继承下来。继承树的低端对象不可避免的膨胀。大多数属性并没有被修改,仍然保持着父类定义时的默认值。
定义依赖属性
例:
// 定义依赖属性
public static readonly DependencyProperty NameProperty;
注册依赖属性
必须在于其关联的静态构造函数中注册
添加属性封装器
public string Title
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
创建属性封装器时,应当只包含对SetValue()和GetValue()方法的调用,不应当添加任何验证属性值的额外代码、引发事件的代码等。这是因为WPF中的其他功能可能会忽略属性封装器,并直接调用SetValue()和GetValue()方法。
属性封装器不是验证数据或引发事件的正确位置,使用依赖属性回调函数(Dependency-Property.Validate ValueCallback回调函数进行验证操作)
当属性变化时,如果希望进行响应,有两种选择--可以使用属性值创建绑定,也可以编写能够自动改变其他属性或开始动画的触发器。
依赖属性的优点:
① 优化了属性的存储,减少了不必要的内存使用
② 加入了属性变化通知,限制,验证等
③ 可以存储多个值,配合人EXpression以及Animation等,打造出更灵活的使用方式
eg:
1 public partial class MainWindow : Window 2 { 3 public MainWindow() 4 { 5 InitializeComponent(); 6 TestTitle testTitle = new TestTitle { Title = "TestData" }; 7 this.stkpnlTest.DataContext = testTitle; 8 } 9 10 public class TestTitle : DependencyObject 11 { 12 public string Title 13 { 14 get { return (string)GetValue(NameProperty); } 15 set { SetValue(NameProperty, value); } 16 } 17 // 定义依赖属性 18 public static readonly DependencyProperty NameProperty = 19 DependencyProperty.Register("Title", typeof(string), typeof(TestTitle)); 20 } 21 }
xaml:
1 <StackPanel x:Name="stkpnlTest"> 2 <TextBox x:Name="txtTest1" 3 Margin="10" 4 Text="{Binding Path=Title}"></TextBox> 5 <TextBox x:Name="txtTest2" 6 Margin="10" 7 Text="{Binding Path=Title}"></TextBox> 8 </StackPanel>
附加属性
1.概念
附加属性是一种依赖属性,不同之处在于附加属性被应用到的类并非定义附加属性的那个类。
定义附加属性
定义附加属性,需要使用RegisterAttached()方法,而不是使用Register()方法
当创建附加属性时,不必定义.NET属性封装器。这是因为附加属性可以被用于任何对象。例如,Grid。Row属性可能被用于Grid对象,也可能被用于其他元素上。
不使用.NET属性封装器,反而附加属性需要调用两个静态方法来设置和获取属性值,这两个方法使用为人熟知的SetValue()和GetValue()方法,这两个方法应当命名为SetPropertyName()和GetPropertyName()。
附加属性与依赖属性的区别
1.附加属性使用的RegisterAttached方法,而依赖属性使用的是Register方法
2.附加属性使用两个方法进行包装,依赖属性使用CLR属性对GetValue和Set Value两个方法进行包装。
3.附加属性被应用到的类并非定义附加属性的那个类,依赖属性被应用到定义附加属性的那个类。