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

  我们举例一段代码。假设有个类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. 19c PDB数据泵迁入

    1.问题描述 用数据泵进行pdb的迁入迁出,模拟测试将其他库的数据导入到19cpdb中 2.环境介绍 source:12.2.0.1.0 target:19.0.0.0.0 3.源端制造数据 创建表空 ...

  2. SpringBoot打jar包-下载文件时报错-class path resource xxxxxx cannot be resolved to URL because it does not exist

    一.问题由来 新项目的开发中,打包方式由war包改为了jar包的方式,这样在部署的时候更加的方便.测试环境使用pm2这个工具来管理项目的运行,停止,重启等等非常方便. 可是当测试人员在测试项目中的文件 ...

  3. go语言json技巧

    go语言json技巧 本文总结了在项目中遇到的那些关于go语言JSON数据与结构体之间相互转换的问题及解决办法. 基本的序列化 首先我们来看一下Go语言中json.Marshal()(系列化)与jso ...

  4. GO学习-(2) 从零开始搭建Go语言开发环境

    从零开始搭建Go语言开发环境 一步一步,从零搭建Go语言开发环境. 安装Go语言及搭建Go语言开发环境 下载 下载地址 Go官网下载地址:https://golang.org/dl/ Go官方镜像站( ...

  5. 5G通讯与芯片

    5G通讯与芯片 美国商务部可能接近达成一项新的规则,允许美国公司与华为重启谈判,在共同制定下一代通信技术5G标准方面进行合作. 华为美国首席安全官安迪·珀迪(Andy Purdy)向第一财经记者独家回 ...

  6. 向Relay添加算子

    向Relay添加算子 为了在Relay IR中使用TVM算子,需要在Relay中注册算子,以确保将其集成到Relay的类型系统中. 注册算子需要三个步骤: 使用RELAY_REGISTER_OPC + ...

  7. 八、Nginx的TCP/UDP调度器

    nginx 1.9后才可以调用其他应用 1.9前只能调用web 部署nginx服务器----配置----起服务.验证 部署nginx服务器: [root@proxy ~]# yum –y instal ...

  8. MySQL零散知识点(01)

    内容概要 --- 表字段操作补充(掌握) --- python操作MySQL(掌握) --- 视图(了解) --- 触发器(了解) --- 存储过程(了解) --- 事务(掌握) --- 内置函数(了 ...

  9. 利用SPI机制实现责任链模式中的处理类热插拔

    最近看到责任链模式的时候每增加一个处理类,就必须在责任链的实现类中手动增加到责任链中,具体代码基本就是list.add(new FilterImpl()),可以看到每次增加一个处理类,就必须添加一行上 ...

  10. JavaScript中基本数据类型和引用数据类型的区别(栈——堆)

    JavaScript中基本数据类型和引用数据类型的区别 1.基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型. 基本数据类型指的是简单的数据段,引用数据 ...