标题太空泛,直接上图

无论是在验证啊,还是提示方面等一些右上角的角标之类的效果,我们会怎么做?

这里介绍一种稍微简单一些的方法,利用附加属性和Adorner来完成。

例如WPF自带的控件上要加这样的效果,首先继承自原控件然后重写是可以的,但是控件类型太多,重写不过来。这个时候我们唯一能添加的只有附加属性了。

利用附加属性的属性变更事件PropertyChangedCallBack,我们可以获取到宿主对象即Button,然后就可以往Button上加入我们自定义的Adorner了。再添加一个附加属性控制Adorner的显示/隐藏,那么就很完美了,这样每个控件只用设置两个附加属性就能拥有上面的效果。下面是核心代码,

附加属性

  1. public class AdornerHelper
  2. {
  3. #region 是否有Adorner
  4. public static bool GetHasAdorner(DependencyObject obj)
  5. {
  6. return (bool)obj.GetValue(HasAdornerProperty);
  7. }
  8.  
  9. public static void SetHasAdorner(DependencyObject obj, bool value)
  10. {
  11. obj.SetValue(HasAdornerProperty, value);
  12. }
  13.  
  14. // Using a DependencyProperty as the backing store for HasAdorner. This enables animation, styling, binding, etc...
  15. public static readonly DependencyProperty HasAdornerProperty =
  16. DependencyProperty.RegisterAttached("HasAdorner", typeof(bool), typeof(AdornerHelper), new PropertyMetadata(false, PropertyChangedCallBack));
  17.  
  18. private static void PropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
  19. {
  20. if ((bool)e.NewValue)
  21. {
  22. var element = d as Visual;
  23.  
  24. if (element != null)
  25. {
  26. var adornerLayer = AdornerLayer.GetAdornerLayer(element);
  27.  
  28. if (adornerLayer!=null)
  29. {
  30. adornerLayer.Add(new NotifyAdorner(element as UIElement));
  31. }
  32. }
  33. }
  34. }
  35. #endregion
  36.  
  37. #region 是否显示Adorner
  38.  
  39. public static bool GetIsShowAdorner(DependencyObject obj)
  40. {
  41. return (bool)obj.GetValue(IsShowAdornerProperty);
  42. }
  43.  
  44. public static void SetIsShowAdorner(DependencyObject obj, bool value)
  45. {
  46. obj.SetValue(IsShowAdornerProperty, value);
  47. }
  48.  
  49. // Using a DependencyProperty as the backing store for IsShowAdorner. This enables animation, styling, binding, etc...
  50. public static readonly DependencyProperty IsShowAdornerProperty =
  51. DependencyProperty.RegisterAttached("IsShowAdorner", typeof(bool), typeof(AdornerHelper), new PropertyMetadata(false,IsShowChangedCallBack));
  52.  
  53. private static void IsShowChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
  54. {
  55. var element = d as UIElement;
  56.  
  57. if (element != null)
  58. {
  59. var adornerLayer = AdornerLayer.GetAdornerLayer(element);
  60. if (adornerLayer!=null)
  61. {
  62. var adorners = adornerLayer.GetAdorners(element);
  63. if (adorners != null && adorners.Count() != )
  64. {
  65. var adorner = adorners.FirstOrDefault() as NotifyAdorner;
  66.  
  67. if (adorner == null)
  68. {
  69. return;
  70. }
  71.  
  72. if ((bool)e.NewValue)
  73. {
  74. adorner.ShowAdorner();
  75. }
  76. else
  77. {
  78. adorner.HideAdorner();
  79. }
  80. }
  81. }
  82. }
  83. }
  84.  
  85. #endregion
  86. }

然后是我们自定义的Adorner效果

  1. public class NotifyAdorner : Adorner
  2. {
  3. private VisualCollection _visuals;
  4. private Canvas _grid;
  5. private Image _image;
  6.  
  7. public NotifyAdorner(UIElement adornedElement)
  8. : base(adornedElement)
  9. {
  10. _visuals = new VisualCollection(this);
  11. _image=new Image()
  12. {
  13. Source = new BitmapImage(new Uri("Notify.png",UriKind.RelativeOrAbsolute)),
  14. Width = ,
  15. Height =
  16. };
  17.  
  18. _grid = new Canvas();
  19. _grid.Children.Add(_image);
  20.  
  21. _visuals.Add(_grid);
  22. }
  23.  
  24. public void ShowAdorner()
  25. {
  26. _image.Visibility = Visibility.Visible;
  27. }
  28.  
  29. public void HideAdorner()
  30. {
  31. _image.Visibility = Visibility.Collapsed;
  32. }
  33.  
  34. protected override int VisualChildrenCount
  35. {
  36. get
  37. {
  38. return _visuals.Count;
  39. }
  40. }
  41.  
  42. protected override Visual GetVisualChild(int index)
  43. {
  44. return _visuals[index];
  45. }
  46.  
  47. protected override Size MeasureOverride(Size constraint)
  48. {
  49. return base.MeasureOverride(constraint);
  50. }
  51.  
  52. protected override Size ArrangeOverride(Size finalSize)
  53. {
  54. _grid.Arrange(new Rect(finalSize));
  55.  
  56. _image.Margin=new Thickness(finalSize.Width-12.5,-12.5,,);
  57.  
  58. return base.ArrangeOverride(finalSize);
  59. }
  60.  
  61. }

这里是源码http://files.cnblogs.com/HelloMyWorld/AdornerSample.rar

大家看代码就能懂了

WPF Adorner+附加属性 实现控件友好提示的更多相关文章

  1. WPF 使用附加属性增加控件属性

    使用附加属性增加控件属性,使得这个附加属性在使用的时候没有局限性,可以在任何的控件中使用它来增加所需要的属性,使得控件的属性使用起来非常灵活 一.自定义附加属性 using System; using ...

  2. WPF Step By Step 控件介绍

    WPF Step By Step 控件介绍 回顾 上一篇,我们主要讨论了WPF的几个重点的基本知识的介绍,本篇,我们将会简单的介绍几个基本控件的简单用法,本文会举几个项目中的具体的例子,结合这些 例子 ...

  3. 设置EditText控件中提示消息hint的字体颜色和大小

    设置EditText控件中提示消息hint的字体颜色和大小 1.设置字体大小 代码例: public void init(){ hint= (EditText) findViewById(R.id.i ...

  4. WPF编程:textbox控件文本框数据显示最后一行

    WPF编程:textbox控件文本框数据显示最后一行 TextBox控件在接收大量数据的时候,滚动条一般在最上方,如何使滚动条随着数据的接收而向下滚动呢?比如有一个TextBox'控件txbRecvD ...

  5. 在WPF中使用WinForm控件方法

    1.      首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2.      在要使用WinForm控 ...

  6. CYQ.Data 支持WPF相关的数据控件绑定(2013-08-09)

    事件的结果 经过多天的思考及忙碌的开发及测试,CYQ.Data 终于在UI上全面支持WPF,至此,CYQ.Data 已经可以方便支持wpf的开发,同时,框架仍保留最低.net framework2.0 ...

  7. .Net中使用无闪刷新控件时提示框不显示

    今天做提示框的时候一直不显示,让我郁闷好久,晚上吃饭的时候问了同事一下,他给了一个思路, 他说可能是因为由于页面中的无闪刷新导致的结果:百度了一下真找到了解决方法 在页面中存在无闪刷新控件的时候提示框 ...

  8. WPF中的image控件的Source赋值

    WPF中的Image控件Source的设置 1.XAML中 简单的方式(Source="haha.png"); image控件的Source设置为相对路径后(Source=&quo ...

  9. WPF后台设置xaml控件的样式System.Windows.Style

    WPF后台设置xaml控件的样式System.Windows.Style 摘-自 :感谢 作者: IT小兵   http://3w.suchso.com/projecteac-tual/wpf-zhi ...

随机推荐

  1. Javascript 优化项目代码技巧之语言基础(二)

        上一篇随笔介绍了如何正确判断对象类型.避免变量污染,特殊值(null.undefined.NaN)的使用,以及其他Javascript中常用关键字与方法的优化,这篇随笔将着重介绍Javascr ...

  2. C#语言基础——数组

    数组 一.一位数组 数组初始化,创建数组,数组长度为5 int[] array = new int[5]; array[0] = 1; array[1] = 2; array[2] = 3; arra ...

  3. MYSQL-GroupCommit

    组提交(group commit)是MYSQL处理日志的一种优化方式,主要为了解决写日志时频繁刷磁盘的问题.组提交伴随着MYSQL的发展不断优化,从最初只支持redo log 组提交,到目前5.6官方 ...

  4. Linux 性能优化工具包 sysstat 以及 sysstat 服务

    1. sysstat service 1.1. /etc/cron.d/sysstat Linux 下的性能分析,少不了要使用 sysstat 工具包中的命令.同时 sysstat 服务会自动每个10 ...

  5. ReactNative之坑爹的在线安装

    编译一个github上ReactNative应用,根据说明只有3步: npm installreact-native run-androidenjoy 但几个步骤实在是一波三折充满着坎坷,一点都不en ...

  6. my_mosaic

    //功能:输入想要打马赛克的坐标点,宽,高以及每个边需要划分的块数进行打马赛克 //只能处理位图,根据不同色深定义depth即可 //还没写从文件头读取图片分辨率 #include<unistd ...

  7. Mysql数据库的通用安装方法

    安装方式简介 Mysql数据库也时不时的用过一段时间,具体使用的功能都比较浅显,没有具体深入学习.最近一段在公司部署iNeedle系统时经常避免不了要安装apache和Mysql数据库.一般Mysql ...

  8. 关于/etc/rc.local以及/etc/init.d

    1. /etc/rc.local    这是使用者自订开机启动程序,把需要开机自动运行的程序写在这个脚本里   --------引用----------------------  在完成 run le ...

  9. linux命令学习(一)—— 文件和目录管理命令

    首先需要知道的是命令提示符 [root@localhost ~] # 当前登录用户(root) 主机名(localhost) 当前所在目录(家目录) 超级用户提示符(#) 普通用户提示符($) 1.1 ...

  10. Ubuntu14.04桌面版基本配置

    最近公司需要用Ubuntu测试一些功能,安装好后绚丽的桌面环境很是吸引人,但切换到字符界面后,发现不少地方与RHEL不一样,连ssh.vim都没有,字符界面玩得不开心. 搜了不少文章,才将基本的功能配 ...