附加依赖项属性是一个属性本来不属于对象自己,但是某些特定场景其他的对象要使用该对象在这种场景下的值。这个值只在这个场景下使用。基于这个需求设计出来的属性。这里主要涉及到一个解耦问题。最大的优势是在特定场景下使用的属性,可以在特定场景下定义。这样业务上不会导致代码全部混在某个模块里。提升代码可维护性。

  我们举例一段代码。假设有个类Person。包含了身份ID(IdentityID),姓名(Name),出生年月(Birth date),性别(gender),民族(Nation)。 有一个School类,包含了年级(grade)。我们把用户所在的年纪通过依赖项属性的形式从Person类中解耦出去。这样就可以更好的设计业务的关联关系。

  我们创建继承自DependencyObject的School类。使用propa 快捷方式创建属性。我们给School添加了一个附加依赖项属性GradeProperty。

代码如下:

  public class School : DependencyObject
{
public static int GetGrade(DependencyObject obj)
{
return (int)obj.GetValue(GradeProperty);
} public static void SetGrade(DependencyObject obj, int value)
{
obj.SetValue(GradeProperty, value);
} // Using a DependencyProperty as the backing store for Grade. This enables animation, styling, binding, etc...
public static readonly DependencyProperty GradeProperty =
DependencyProperty.RegisterAttached("Grade", typeof(int), typeof(School), new PropertyMetadata(0));
}

  我们继续创建Person类,使用propdp创建。因为我们已经学习了依赖项属性,所以我们只使用依赖项属性来创建所有Person下的属性对象。

 public class Person : DependencyObject
{
public string IdentityID
{
get { return (string)GetValue(IdentityIDProperty); }
set { SetValue(IdentityIDProperty, value); }
} // Using a DependencyProperty as the backing store for IdentityID. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IdentityIDProperty =
DependencyProperty.Register("IdentityID", typeof(string), typeof(Person)); public string Name
{
get { return (string)GetValue(NamePropertyProperty); }
set { SetValue(NamePropertyProperty, value); }
} // Using a DependencyProperty as the backing store for NameProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty NamePropertyProperty =
DependencyProperty.Register("Name", typeof(string), typeof(Person)); public DateTime BirthDate
{
get { return (DateTime)GetValue(BirthDateProperty); }
set { SetValue(BirthDateProperty, value); }
} // Using a DependencyProperty as the backing store for BirthDate. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BirthDateProperty =
DependencyProperty.Register("BirthDate", typeof(DateTime), typeof(Person)); public bool Gender
{
get { return (bool)GetValue(GenderProperty); }
set { SetValue(GenderProperty, value); }
} // Using a DependencyProperty as the backing store for Gender. This enables animation, styling, binding, etc...
public static readonly DependencyProperty GenderProperty =
DependencyProperty.Register("Gender", typeof(bool), typeof(Person)); public string Nation
{
get { return (string)GetValue(NationProperty); }
set { SetValue(NationProperty, value); }
} // Using a DependencyProperty as the backing store for Nation. This enables animation, styling, binding, etc...
public static readonly DependencyProperty NationProperty =
DependencyProperty.Register("Nation", typeof(string), typeof(Person)); }

  我们创建一个按钮来给Person设置一个附加依赖项属性。学校的年级。

xaml代码和对应的cs代码:

  <Button Content="点击给Pserson对象在对应的业务上附加依赖性属性" Click="AddPsersonAttachedProperty_Click"/>
 private void AddPsersonAttachedProperty_Click(object sender, RoutedEventArgs e)
{
Person person = new Person();
School.SetGrade(person, 1);
var grade = School.GetGrade(person);
MessageBox.Show(grade.ToString()) ;
}

我门通过点击按钮创建了一个Person对象。使用School.SetGrade(person,1)来调用了我门添加在School类下面的附加依赖项属性。我门给Person设置了附加依赖项属性,是School下的Grade依赖项属性值为1。关键点:附加依赖项属性的适用场景是给当前对象添加在某些场景下使用的属性值。  这个时候我们可以使用School.GetGrade(person)读取这个对象中的依赖项属性。依赖项属性理解到这里就行。Grid和子元素在Grid中放置行列的原理和这个对依赖项属性使用是一样的。只是有一些后续的逻辑。目前只要会使用能看懂就好。后续会在自定义控件中,设计自己的布局呈现控件时,在设计阶段讲解哪些应该使用依赖项属性,哪些使用附加依赖项属性。

用一个通过附加属性移动Slider控制小球在Canvas下的例子。 给一个不存在Left 和top属性的小球。添加一个在父容器canvas的附加依赖属性,用来控制小球在Canvas下的位置。附加依赖项属性,主要用于解耦。这篇文章就结束拉。

 <Canvas>
<Slider x:Name="sliderX" Canvas.Top="10" Canvas.Left="10" Width="200" Minimum="50" Maximum="200"/>
<Slider x:Name="sliderY" Canvas.Top="40" Canvas.Left="10" Width="200" Minimum="50" Maximum="200"/>
<Ellipse Fill="Blue" Width="30" Height="30" Canvas.Left="{Binding ElementName=sliderX,Path=Value}" Canvas.Top="{Binding ElementName=sliderY,Path=Value}"/>
</Canvas>

我们使用Canvas作为画板,在里面放入2个Slider一个控制水平位置,一个控制垂直位置。我们通过绑定Slider的Value到Ellipse在Canvas下的附加依赖项属性Canvas.Left和Canvas.Top来

控制小球的垂直和水平位置。来演示如何解耦Ellipse和canvas的布局关系。通过前面了解的的binding、依赖项属性和附加依赖项属性,发现写代码的思路是不是一下就改变了很多?耦合正在慢慢的从设计层就变低了。

我创建了一个C#相关的交流群。用于分享学习资料和讨论问题。欢迎有兴趣的小伙伴:QQ群:542633085

WPF教程五:附加依赖项属性的更多相关文章

  1. WPF学习系列之二 (依赖项属性)

    依赖属性;(dependency property)  它是专门针对WPF创建的,但是WPF库中的依赖项属性都使用普通的.NET属性过程进行了包装.从而可能通过常规的方式使用它们,即使使用他们的代码不 ...

  2. WPF教程四:字段、属性、依赖项属性的演变过程

    这个章节主要讲解属性是什么,为什么会演变出依赖项属性,依赖属性的优势是什么.以及如何更好的使用属性和依赖项属性. 一.属性 属性是什么. 翻了好几本C#的书和微软的文档,我觉得对属性讲解比较好理解的就 ...

  3. [转]WPF 依赖项属性

    from:http://blog.csdn.net/datoumimi/article/details/8033682 ps:环境限制,发的东西一长就会被拦截,所以删了一部分 UI软件中经常会用到大量 ...

  4. 浅谈WPF依赖项属性

    浅谈WPF依赖项属性 0. 引言 依赖项属性虽然在使用上和CLR属性一样,但是它是WPF特有的,不同于CLR属性.只是封装为我们常用CLR的属性,在语法使用上和CLR属性一样.WPF中一些功能:动画, ...

  5. WPF的依赖项属性

    WPF的依赖项属性 属性与事件是.NET抽象模型的核心部分.WPF使用了更高级的依赖项属性(Dependency Property)功能来替换原来.NET的属性,实现了更高效率的保存机制,还添加了附加 ...

  6. WPF中的依赖项属性

    Form cnblogs 桂素伟 随着WPF的推广,不得不重新拾起WPF来,因为这块的产品越来越多. 只能跟着MSDN来学了,所以想是在这里记录下学习的过程和对知识的理解. 先从最基本的吧,依赖项属性 ...

  7. 学习WPF——初识依赖项属性

    入门 首先创建一个依赖项属性 然后绑定父容器的DataContext到这个依赖项的实例 接着绑定子元素的属性到依赖项属性(注意Button的Content属性) 程序最终的运行结果:   说明 首先是 ...

  8. 迟到的 WPF 学习 —— 依赖项属性

    本章学习依赖项属性,英文原文 Dependency Property,它是传统 .Net Framework 属性的扩展,是 WPF 的专属,但所幸使用起来和传统属性几乎一样.WPF 元素所提供的大多 ...

  9. WPF中的依赖项属性(转)

    出处:https://www.cnblogs.com/axzxs2001/archive/2010/04/25/1719857.html 随着WPF的推广,不得不重新拾起WPF来,因为这块的产品越来越 ...

随机推荐

  1. Jquery 常用方法及实例(Day_15)

    想要做一件事,永远都不要怕晚.只要你开始做了,就不晚. 而若是你不开始,仅仅停留在思考.犹豫甚至焦虑的状态,那就永远都是零. mouseover() / mouserout() 当鼠标进入 / 离开某 ...

  2. 企业实施CRM系统后的积极作用

    公司在发展过程中,可能会遇到各种各样的问题,尤其是来自客户的问题,是最令广大企业头痛的.这并不是一个单方面的问题,不仅涉及到员工也涉及到企业.因此,许多企业使用CRM客户管理系统来管理客户,并通过它来 ...

  3. Java核心技术卷阅读随笔--第2章【Java 程序设计环境】

    Java 程序设计环境 本章主要介绍如何安装 Java 开发工具包( JDK ) 以及如何编译和运行不同类型的程序: 控制台程序. 图形化应用程序以及 applet.运行 JDK 工具的方法是在终端窗 ...

  4. object_pool对象池

    object_pool对象池 object_pool是用于类实例(对象)的内存池,它能够在析构时调用所有已经分配的内存块调用析构函数,从而正确释放资源,需要包含以下头文件: #include < ...

  5. VMware vCenter Server 7.0 U2b/6.7 U3n/6.5 U3p,修复 vSphere Client 高危安全漏洞

    vSphere Client(HTML5)中的多个漏洞已秘密报告给 VMware.这里提供了更新和解决方法来解决受影响的 VMware 产品中的这些漏洞. 详见:VMSA-2021-0010 威胁描述 ...

  6. spring模板

    applicationContext <?xml version="1.0" encoding="UTF-8"?> <beans xmlns= ...

  7. Python+Selenium学习笔记14 - python官网的tutorial - just() fill() format()

    repr(x).rjust(n)  左侧空格填充,右侧列对齐,str()和repr()是一种输出,也可不用,直接x.rjust() repr(x).ljust(n)  右侧空格填充,左侧列对齐 rep ...

  8. 手把手教你实现三种绑定方式(call、apply、bind)

    关于绑定首先要说下this的指向问题. 我们都知道: 函数调用时this指向window 对象调用函数时this指向对象本身 看下面得例子: // 1 function test(){ const n ...

  9. OpenCV读写视频文件解析(二)

    OpenCV读写视频文件解析(二) VideoCapture::set 设置视频捕获中的属性. C++:bool VideoCapture::set(int propId, double value) ...

  10. Python分析离散心率信号(下)

    Python分析离散心率信号(下) 如何使用动态阈值,信号过滤和离群值检测来改善峰值检测. 一些理论和背景 到目前为止,一直在研究如何分析心率信号并从中提取最广泛使用的时域和频域度量.但是,使用的信号 ...