c# wpf如何附加依赖项属性

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

  我们举例一段代码。假设有个类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# wpf如何附加依赖项属性的详细内容,更多关于c# wpf附加依赖项属性的资料请关注我们其它相关文章!

(0)

相关推荐

  • c# wpf如何更好的使用Application程序集资源

    这一篇单独拿出来分析这个程序集资源,为的就是不想让大家把程序集资源和exe程序强关联,因为程序集资源实际上是二进制资源,后续编译过程中会被嵌入到程序集中,而为了更方便的使用资源,我们要好好梳理一下程序集资源相关的知识.(例如多语言资源,多工程.多项目使用的公共资源文件). 1)在程序集中添加资源 我们通过向项目添加文件并尝试修改资源文件属性看有什么不同的结果. 在工程上右键=>添加=>新建文件夹=>改名为Images=>回车=>在Images文件夹上右键=>添加=>

  • C# WPF如何反射加载Geometry几何图形数据图标

    相信大家在阅读WPF相关GitHub开源项目源码时都会看见一串串这种数据 这种Geometry数据就是几何图形数据 为什么要用Geometry数据做图标? 有一种做法是使用ttf字体文件代替,不过使用ttf字体文件会出现下面几个缺点: 1.团队协作不便于管理 2.需要依赖特定平台 3.无法灵活使用 而使用Geometry的话,我们可以将这些几何图形数据存入资源字典ResourceDictionary 通过反射进行灵活使用,团队开发可共同维护 怎么获取Geometry数据? 我们进入https:/

  • c# WPF中的TreeView使用详解

    在wpf中实现treeview的功能,可能看到很多分享的都是简单的绑定,仅此记录自己完成的功能. 前台 <TreeView x:Name="chapterTree" Grid.Column="0" SelectedItemChanged="chapterTree_SelectedItemChanged" PreviewMouseRightButtonDown="chapterTree_PreviewMouseRightButton

  • 详解WPF中的对象资源

    在WPF中,所有继承自FrameworkElement的元素都包含一个Resources属性,这个属性就是我们这篇要讲的资源. 这一篇讲解的资源是不是上一篇的程序集资源(那个是在编译过程中打包到程序集中),这个是资源是我们想在公共的地方写一个对象让其他元素重复使用. 先贴个例子: <Window x:Class="NETResource.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/pre

  • 详解WPF的InkCanvas选择模式

    InkCanvas是WPF中进行墨迹绘制的控件,本文介绍下InkCanvas控件是如何进行选择操作的.文中有误的地方希望大家进行批评指正. InkCanvas的选择效果 使用WPF可以轻松实现白板功能,只需要添加一个InkCanvas控件.修改InkCanvas的EditingMode属性可以控制InkCanvas的操作模式,如书写.选择.擦除等模式. 如下demo在窗口中添加一个InkCanvas,然后添加一个Button实现书写与选择模式的切换. // xaml <Grid> <In

  • C# WPF实现的语音播放自定义控件

    原理很简单,利用Path画一个图,然后用动画进行播放,播放时间由依赖属性输入赋值与控件内部维护的一个计时器进行控制. 控件基本是玩具,无法作为真实项目使用. 因为没有设置播放源,所以编写异步播放源或者实际播放时候要将事件引发,是否播放等属性,事件移到真实播放事件 非专业UI,即使知道怎么画图也是画的不如意,到底是眼睛会了,手不行啊. 主界面xaml <local:VoiceAnimeButton Height="40" Width="200" IconMarg

  • 详解WPF中的隧道路由和冒泡路由事件

    WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇开始整理事件的用法和什么是直接路由,什么是冒泡路由,以及什么是隧道路由. 事件最基本的用法 在基于事件驱动的开发中,把代码放在响应注册的事件的处理函数内,比如Click事件.MouseDown事件.MouseUp事件等等.每个控件响应自己的注册事件,有很多如果在事件上有相互关联和影响的事件,就要在一个业务逻辑里写比较多的代码.而路由事件主要的优势就是路由事件可以在元素树上进行传递,并且沿着

  • c# 基于GMap.NET实现电子围栏功能(WPF版)

    前言 GMap.NET是一个强大.免费.跨平台.开源的.NET控件.分为WPF和winform版.GMap.NET的基本知识不做过多介绍,本文主要介绍如何使用该控件实现电子围栏功能. 电子围栏主要有两个功能模块:界面展示围栏区域,判断人员出入围栏的逻辑.GMap.NET的WPF版本功能并不强大,实现一些复杂的功能就只能发掘WPF的潜力了.GMap.NET给我们提供了一个基本的平台,必须熟练掌握WPF才能开发出复杂gis产品. 围栏区域界面显示 1 认识 GMapMarker GMapContro

  • c# wpf使用GMap.NET类库,实现地图轨迹回放

    前言 实现轨迹回放,GMap.NET有对应的类GMapRoute.这个类函数很少,功能有限,只能实现简单的轨迹回放.要实现更复杂的轨迹回放,就需要自己动手了. 本文介绍一种方法,可以实现复杂的轨迹回放.有句话"功夫在诗外",GMap.NET给你提供了基本地图处理功能:但是不要让CMap.NET束缚了手脚.你需要有深刻理解地图实现原理,深入理解WPF动画的原理,才能到达随心所欲.最终的效果如下: GMap.NET 显示原理 地图就是由许多方格"瓦片"组合而来.当你移动

  • 通过App.xaml理解wpf中的Application类

    这个章节来了解Application类,我考虑了一晚上决定跳过控件类相关的学习,因为控件如果只是入门的话每个控件F12跳过去看一下属性.事件就能大致了解的差不多,而且控件比较多,每个都这样看一遍,感觉意义不大.同时控件的使用一般又同时包含了,资源.样式.触发器.模板.绑定.列表控件的话,可能还包含列表虚拟化和数据虚拟化.所以想了一下.打算先讲Application类. 教程的第一篇我们从hello world开始了解什么是程序.它是如何编译.生成和运行的.现在这一个篇从App.xaml讲解App

  • c# wpf如何使用Blend工具绘制Control样式

    本文通过设计一个RadioButton,分享下使用Blend绘制Path的方法.待绘制的RadioButton样式如下文所示,如有更好的方法实现该样式,欢迎交流. 实现效果 将要实现的RadioButton样式如下图,可以看出按钮的笔尖和笔身的填充色,以及选中时右上方圆形的填充色一致,代表笔的颜色. 实现方式 笔身使用矩形,填充色绑定按钮背景色:笔头部分使用闭合的Path,其中笔尖的颜色同样绑定按钮背景色:右上方的圆形使用Ellipse,填充色同样绑定按钮背景色. 实现步骤 1.打开Blend,

随机推荐