Dependency,字面意思为依靠,依赖; 附属国; 附属地;这里为什么会有DependencyObject类的存在?这还要从WPF的依赖属性系统说起。
如果您有Winform的基础,对于控件属性值的赋值一定不陌生。比如:
button1.Text = "确定";
我们将“确定”字符串赋值给一个按钮的Text属性,这样前端的button1的内容为显示为”确定“。如果根据某些业务要求,需要将这个button1的内容翻译成英语“OK"显示呢?其实也很简单。
button1.Text = "OK";
这种在需要的时候主动去改变控件的值的开发模式,我们称为事件驱动模式。
一直以来, 我们都采用事件驱动模式开发软件。也没觉得有多少不便,如果控件的相关属性值需要被多个地方反复改动,大不了我们多写几行代码。那有没有更省事的方式呢?微软说,有!
于是微软在WPF框架中推出了更省事的处理方式——数据驱动模式。什么是数据驱动模式?控件的属性不再被直接赋值,而是绑定了另一个”变量“,当这个”变量“发生改变时,控件的属性也会跟着改变,这样的属性也被称为依赖属性。这有点像初中数学中的y=x这样的函数,y是因变量,x是自变量,y随着x的变化而变化。
我在这里只是比较形象地分享数据驱动模式中一部分概念,因为您可能是第一定接触到这个概念。关于更详细的知识,我们会在后面专门拿一小节来全面的讲解数据驱动模式。
我迫不及待的抛出数据驱动模式,是因为几乎WPF控件的所有属性都可以采用这种模式去更新属性的值,为什么?因为所有控件都继承了DependencyObject这个基类。换句话说,也只有继承了这个基类的控件,才能享受这一特殊待遇。其背后的原理是有一个强大的依赖属性系统在提供属性更改通知服务。
提前阅读
DependencyObject 类表示参与依赖属性系统的对象。属性系统的主要功能是计算属性的值,并提供有关已更改的值的系统通知。 参与属性系统的另一个类 DependencyProperty。 DependencyProperty 允许将依赖属性注册到属性系统,并提供有关每个依赖属性的标识和信息,而 DependencyObject 为基类,使对象能够使用此依赖属性。INotifyPropertyChanged 类用于通知UI刷新,注重的仅仅是数据更新后的通知。DependencyObject 类用于给UI添加依赖和附加属性,注重数据与UI的关联。如果简单的数据通知,两者都可以实现的。
我们来看一下DependencyObject类的定义,比较常用的是GetValue和SetValue。GetValue表示获取某一个依赖属性的值,由于不确定这个值是什么类型,所以微软把这个函数的返回值设计成object。SetValue表示设置某一个依赖属竹的值,所有它有两个参数,第一个参数dp表示要设置的依赖属性,第二个参数value表示新值。
public class DependencyObject : DispatcherObject
{
public DependencyObject();
public DependencyObjectType DependencyObjectType { get; }
public bool IsSealed { get; }
public void ClearValue(DependencyProperty dp);
public void ClearValue(DependencyPropertyKey key);
public void CoerceValue(DependencyProperty dp);
public sealed override bool Equals(object obj);
public sealed override int GetHashCode();
public LocalValueEnumerator GetLocalValueEnumerator();
public object GetValue(DependencyProperty dp);
public void InvalidateProperty(DependencyProperty dp);
public object ReadLocalValue(DependencyProperty dp);
public void SetCurrentValue(DependencyProperty dp, object value);
public void SetValue(DependencyProperty dp, object value);
public void SetValue(DependencyPropertyKey key, object value);
protected virtual void OnPropertyChanged(DependencyPropertyChangedEventArgs e);
protected internal virtual bool ShouldSerializeProperty(DependencyProperty dp);
}
关于依赖属性我们会在后面为大家做专题讲述。下一节,我们来讨论一下Visual基类。
——重庆教主 2023年8月13日