zoukankan      html  css  js  c++  java
  • 依赖项属性

    依赖项属性时WPF对.NET属性系统的扩展,用途在于提供一种方法来基于其他输入的值计算属性值,也就是说依赖项属性的值可能是通过以下途径获取:1.通过主题和用户首选项等系统属性;2.通过数据绑定或动画等来实时确定;3.通过资源和样式;4通过在元素树中的父子关系继承而来等。而且依赖项属性可通过独立验证、默认值、回调方法来修改属性值。
    下面来看看定义一个依赖项属性的过程:
    1. 定义依赖项属性
    依赖项属性对象都是DependencyProperty类的实例,且考虑到依赖项属性可以被父子元素之间继承,即在不同类之间共享,所以依赖项属性都为静态字段。如下:
    public static readonly DependencyProperty MarginProperty;
    2 注册依赖项属性
    通过以下代码注册依赖项属性:
    FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(
    new Thickness(), FrameworkPropertyMetadataOption.AffectsMeasure);
    MarginProperty = DependencyProperty.Register("Margin", 
    typedef(Thickness), typeof(FrameworkElement), metadata,
    new ValidateValueCallback(FrameworkElement.IsMarginValid));
    注册依赖项属性要经过上面两步:
    1.定义依赖项属性
    创建FrameworkPropertyMetadata对象作为依赖项属性的默认值。上例中使用的构造函数中第一个参数为默认值,第二个参数为确定概述行的行为(如值更改发生的时间是否属性值继承等)。还有另一些重载的构造函数,有的含有指定属性值改变时的回调函数;
    2. 注册依赖项属性
    然后通过DependencyProperty.Register方法注册事件,第一个参数确定依赖项属性的名称,第二个参数确定依赖项属性值的类型,第三个参数确定依赖项属性的所有者,第四个参数确定默认值,最后一个参数确定验证属性的回调函数
    3. 添加属性包装器
    依赖项属性的存取器要使用DependencyObject中的GetValue和SetValue方法来存取,示例如下:
    public Thickness Margin
    {
    set { SetValue(MarginProperty, value); }
    get { return (Thickness)GetValue(MarginProperty); }
    }
    如上过程便可创建一个依赖项属性。
    依赖项属性的一个重要功能是动态值识别,WPF确定一个属性的值会按下列顺序确定基本值:
    1. 默认值
    2. 继承而来的值
    3. 来自主题样式的值
    4. 来自项目样式的值
    5. 本地值
    而基本值未必是最后从属性中检索到的值,因为还存在其他改变属性值的提供者。所以WPF决定属性值得过程为:
    1. 确定基本值
    2. 如果属性值是个表达式,则对表达式进行求值
    3. 如果属性是动画的目标,则应用动画
    4. 调用回调函数修正属性值
    下面使用一个完整的示例展示依赖项属性的使用。在WPF中没有通知栏控件,所以这儿使用WinForm中的NotifyIcon控件封装出一个WPF通知控件,具体代码如下:
      1 public class NotificationAreaIcon : FrameworkElement
      2 {
      3 //对Forms.NotifyIcon控件封装
      4 public static Forms.NotifyIcon notifyIcon;
      5 
      6 //添加鼠标点击路由事件
      7 public static readonly RoutedEvent MouseClickEvent = EventManager.RegisterRoutedEvent(
      8 "MouseClick", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(NotificationAreaIcon));
      9 
     10 //添加鼠标双击路由事件
     11 public static readonly RoutedEvent MouseDoubleClickEvent = EventManager.RegisterRoutedEvent(
     12 "MouseDoubleClick", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(NotificationAreaIcon));
     13 
     14 //注册依赖项属性Icon
     15 public static readonly DependencyProperty IconProperty =
     16 DependencyProperty.Register("Icon", typeof(ImageSource), typeof(NotificationAreaIcon));
     17 
     18 //注册依赖项属性Text
     19 public static readonly DependencyProperty TextProperty =
     20 DependencyProperty.Register("Text", typeof(string), typeof(NotificationAreaIcon));
     21 
     22 //注册依赖项属性MenuItems
     23 public static readonly DependencyProperty FormsContextMenuProperty =
     24 DependencyProperty.Register("MenuItems", typeof(List<Forms.MenuItem>), typeof(NotificationAreaIcon), new PropertyMetadata(new List<Forms.MenuItem>()));
     25 
     26 //初始化事件
     27 protected override void OnInitialized(EventArgs e)
     28 {
     29 base.OnInitialized(e);
     30 
     31 // Create and initialize the window forms notify icon based
     32 notifyIcon = new Forms.NotifyIcon();
     33 notifyIcon.Text = Text;
     34 if (!DesignerProperties.GetIsInDesignMode(this))
     35 {
     36 notifyIcon.Icon = FromImageSource(Icon);
     37 }
     38 notifyIcon.Visible = FromVisibility(Visibility);
     39 
     40 if (this.MenuItems != null && this.MenuItems.Count > 0)
     41 {
     42 notifyIcon.ContextMenu = 
     43 new System.Windows.Forms.ContextMenu(this.MenuItems.ToArray());
     44 }
     45 
     46 notifyIcon.MouseDown += OnMouseDown;
     47 notifyIcon.MouseUp += OnMouseUp;
     48 notifyIcon.MouseClick += OnMouseClick;
     49 notifyIcon.MouseDoubleClick += OnMouseDoubleClick;
     50 
     51 Dispatcher.ShutdownStarted += OnDispatcherShutdownStarted;
     52 }
     53 
     54 private void OnDispatcherShutdownStarted(object sender, EventArgs e)
     55 {
     56 notifyIcon.Dispose();
     57 }
     58 
     59 public void DestroyIcon()
     60 {
     61 notifyIcon.Dispose();
     62 }
     63 
     64 private void OnMouseDown(object sender, Forms.MouseEventArgs e)
     65 {
     66 OnRaiseEvent(MouseDownEvent, new MouseButtonEventArgs(
     67 InputManager.Current.PrimaryMouseDevice, 0, ToMouseButton(e.Button)));
     68 }
     69 
     70 private void OnMouseUp(object sender, Forms.MouseEventArgs e)
     71 {
     72 OnRaiseEvent(MouseUpEvent, new MouseButtonEventArgs(
     73 InputManager.Current.PrimaryMouseDevice, 0, ToMouseButton(e.Button)));
     74 }
     75 
     76 private void OnMouseDoubleClick(object sender, Forms.MouseEventArgs e)
     77 {
     78 OnRaiseEvent(MouseDoubleClickEvent, new MouseButtonEventArgs(
     79 InputManager.Current.PrimaryMouseDevice, 0, ToMouseButton(e.Button)));
     80 }
     81 
     82 private void OnMouseClick(object sender, Forms.MouseEventArgs e)
     83 {
     84 OnRaiseEvent(MouseClickEvent, new MouseButtonEventArgs(
     85 InputManager.Current.PrimaryMouseDevice, 0, ToMouseButton(e.Button)));
     86 }
     87 
     88 private void OnRaiseEvent(RoutedEvent handler, MouseButtonEventArgs e)
     89 {
     90 e.RoutedEvent = handler;
     91 RaiseEvent(e);
     92 }
     93 
     94 public List<Forms.MenuItem> MenuItems
     95 {
     96 get { return (List<Forms.MenuItem>)GetValue(FormsContextMenuProperty); }
     97 set { SetValue(FormsContextMenuProperty, value); }
     98 }
     99 
    100 public ImageSource Icon
    101 {
    102 get { return (ImageSource)GetValue(IconProperty); }
    103 set { SetValue(IconProperty, value); }
    104 }
    105 
    106 public string Text
    107 {
    108 get { return (string)GetValue(TextProperty); }
    109 set { SetValue(TextProperty, value); }
    110 }
    111 
    112 public event MouseButtonEventHandler MouseClick
    113 {
    114 add { AddHandler(MouseClickEvent, value); }
    115 remove { RemoveHandler(MouseClickEvent, value); }
    116 }
    117 
    118 public event MouseButtonEventHandler MouseDoubleClick
    119 {
    120 add { AddHandler(MouseDoubleClickEvent, value); }
    121 remove { RemoveHandler(MouseDoubleClickEvent, value); }
    122 }
    123 
    124 #region Conversion members
    125 
    126 private static Drawing.Icon FromImageSource(ImageSource icon)
    127 {
    128 if (icon == null)
    129 {
    130 return null;
    131 }
    132 Uri iconUri = new Uri(icon.ToString());
    133 return new Drawing.Icon(Application.GetResourceStream(iconUri).Stream);
    134 }
    135 
    136 private static bool FromVisibility(Visibility visibility)
    137 {
    138 return visibility == Visibility.Visible;
    139 }
    140 
    141 private MouseButton ToMouseButton(Forms.MouseButtons button)
    142 {
    143 switch (button)
    144 {
    145 case Forms.MouseButtons.Left:
    146 return MouseButton.Left;
    147 case Forms.MouseButtons.Right:
    148 return MouseButton.Right;
    149 case Forms.MouseButtons.Middle:
    150 return MouseButton.Middle;
    151 case Forms.MouseButtons.XButton1:
    152 return MouseButton.XButton1;
    153 case Forms.MouseButtons.XButton2:
    154 return MouseButton.XButton2;
    155 }
    156 throw new InvalidOperationException();
    157 }
    158 
    159 #endregion Conversion members
    160 }





  • 相关阅读:
    Oracle 用 sqlprompt 修改 sqlplus 提示符
    Oracle cursor pin S wait on X 等待事件 说明
    Oracle 利用 rowid 提升 update 性能
    Oracle 从缓存里面查找真实的执行计划
    Linux 进程状态 说明
    Oracle 用户 对 表空间 配额(quota ) 说明
    Upon startup of Linux database get ORA27102: out of memory LinuxX86_64 Error: 28: No space left on device
    异常宕机 Ora00600 [Kccpb_sanity_check_2] 错误解决方法
    Oracle ORA04031 错误 说明
    Oracle Shared pool 详解
  • 原文地址:https://www.cnblogs.com/lvniao/p/3564611.html
Copyright © 2011-2022 走看看