照书学WPF之 Dependency Property 1

简介

Dependency Property: 它们依赖一些其他的property和外在的影响,引起自身的变化.

如: WPF框架的编程经常和界面打交道,经常遇到的一个情况是某个属性的值的变化会影响到多个其他对象。比如当一个Button的改变大小超过了它的容器,他的容器应该自动调整大小。于是我们考虑在每个属性的set方法中触发一些事件,但很快我们发现现有的功能很难满足我们的需求,至少不能简洁漂亮的满足这些需求。

 定义示例: public static readonly DependencyProperty FontSizePropery;

1.简单的element tree

 通过简单的例子来理解"沿袭"(不能说是继承)

窗口构造函数将Font size 初使化为16设备无关的单位. 所有的BUTTON都会沿袭这个设置(都是WINDOW的孩子)

ContractedBlock.gif ExpandedBlockStart.gif Code
 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.Windows;
 5using System.Windows.Controls;
 6using System.Windows.Documents;
 7
 8namespace DockAndGrid
 9ExpandedBlockStart.gifContractedBlock.gif{
10    public class SetFontSizeProperty : Window
11ExpandedSubBlockStart.gifContractedSubBlock.gif    {
12        [STAThread]
13        public static void Main()
14ExpandedSubBlockStart.gifContractedSubBlock.gif        {
15            Application app = new Application();
16            app.Run(new SetFontSizeProperty());
17        }

18
19        public SetFontSizeProperty()
20ExpandedSubBlockStart.gifContractedSubBlock.gif        {
21            Title = "Set size property";
22            SizeToContent = SizeToContent.WidthAndHeight;
23            ResizeMode = ResizeMode.CanMinimize;
24            FontSize = 16;
25ExpandedSubBlockStart.gifContractedSubBlock.gif            Double[] fntsizes = 8,16,32};
26
27            Grid grid = new Grid();
28            Content = grid;
29
30            for (int i = 0; i < 2; i++)
31ExpandedSubBlockStart.gifContractedSubBlock.gif            {
32                RowDefinition row = new RowDefinition();
33                row.Height = GridLength.Auto;
34                grid.RowDefinitions.Add(row);
35            }

36            for (int i = 0; i < fntsizes.Length; i++)
37ExpandedSubBlockStart.gifContractedSubBlock.gif            {
38                ColumnDefinition col = new ColumnDefinition();
39                col.Width = GridLength.Auto;
40                grid.ColumnDefinitions.Add(col);
41            }

42
43            for (int i = 0; i < fntsizes.Length; i++)
44ExpandedSubBlockStart.gifContractedSubBlock.gif            {
45                Button btn = new Button();
46                btn.Content =  new TextBlock(new Run("Set Window FontSize to " + fntsizes[i]));
47                btn.Tag = fntsizes[i];
48                btn.HorizontalAlignment = HorizontalAlignment.Center;
49                btn.VerticalAlignment = VerticalAlignment.Center;
50                btn.Click += this.WindowFontSizeOnClick;
51                grid.Children.Add(btn);
52                Grid.SetRow(btn, 0);
53                Grid.SetColumn(btn, i);
54
55                btn = new Button();
56                btn.Content = new TextBlock(new Run("Set Button FontSize to " + fntsizes[i]));
57                btn.Tag = fntsizes[i];
58                btn.HorizontalAlignment = HorizontalAlignment.Center;
59                btn.VerticalAlignment = VerticalAlignment.Center;
60                btn.Click += this.ButtonFontSizeOnClick;
61                grid.Children.Add(btn);
62                Grid.SetRow(btn, 1);
63                Grid.SetColumn(btn, i);
64            }

65        }

66
67        void WindowFontSizeOnClick(object sender, RoutedEventArgs args)
68ExpandedSubBlockStart.gifContractedSubBlock.gif        {
69            Button btn = args.Source as Button;
70            FontSize = (double)btn.Tag;
71        }

72
73        void ButtonFontSizeOnClick(object sender, RoutedEventArgs args)
74ExpandedSubBlockStart.gifContractedSubBlock.gif        {
75            Button btn = args.Source as Button;
76            btn.FontSize = (double)btn.Tag;
77        }

78
79    }

80}

81

 element tree是我们能看到的(实际)能看到的视觉对像, 是对logic tree的简单处理,更容易理解程序 (font size如何被处理的), 在此程序中为window->grid->(button collection)->(textblock collection)

特点:树中较低的对像"沿袭"父亲的property,然而如果某个对像有明确的设定自己的font size,那么就不用沿袭父亲的这个property

注: Grid根本就没有fontsize property,但依然可以沿袭(内部机制,不是很明白)

 property set priority: 对像自己的设定> 沿袭来的值 > 默认值

 

2. dependecy property 示例

在WPF中,dependency property的使用,允许以一般的方式自动进行大部分的通知.

定义:  public static readonly DependencyProperty SpaceProperty;

它是public and static, 此成员只与类相关,而非与对象相关联.

注册:  SpaceProperty =  DependencyProperty.Register.("Name", typeof(datatype), typeof(ownertype));

实际上这个property不可以简单的这么完成,还要须要元数据等元素,并且由于是静态的成员,必须在静态构造函数中初使化

static SpaceButton()
        {
            //define metadata
            FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
            metadata.DefaultValue = 1;
            metadata.AffectsMeasure = true;
            metadata.Inherits = true;
            metadata.PropertyChangedCallback += OnSpacePropertyChanged;

            //Register dependency property
            SpaceProperty = DependencyProperty.Register("Space", typeof(int), typeof(SpaceButton),
                metadata, ValidateSpaceValue);

        }

ValidateSpaceValue: 检验值是否合法

AffectsMeasure: 影响控件的尺寸调整.

使用: .Net CLR wrapper

public int Space
        {
            set { SetValue(SpaceProperty, value); }
            get { return (int)GetValue(SpaceProperty); }

        }

注意:即使传到SetValue and GetValue方法内当参数的property的对象是静态的,而这两个方法却是实例方法, 它们的值的设定和取得都和特定的实例有关, 这个property维持目前的值,且处理所有的日常事务.

完整示例:

ContractedBlock.gif ExpandedBlockStart.gif Code
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.Windows;
  6using System.Windows.Controls;
  7using System.Windows.Media;
  8using System.Windows.Input;
  9
 10namespace DependencyProperty1
 11ExpandedBlockStart.gifContractedBlock.gif{
 12    class SpaceButton : Button
 13ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 14        string txt;
 15        public string Text
 16ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 17ExpandedSubBlockStart.gifContractedSubBlock.gif            get return txt; }
 18            set
 19ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 20                txt = value;
 21                Content = SpaceOutText(txt);
 22            }

 23        }

 24
 25        public static readonly DependencyProperty SpaceProperty;
 26        public int Space
 27ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 28ExpandedSubBlockStart.gifContractedSubBlock.gif            set { SetValue(SpaceProperty, value); }
 29ExpandedSubBlockStart.gifContractedSubBlock.gif            get return (int)GetValue(SpaceProperty); }
 30        }

 31
 32        static SpaceButton()
 33ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 34            //define metadata
 35            FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
 36            metadata.DefaultValue = 1;
 37            metadata.AffectsMeasure = true;
 38            metadata.Inherits = true;
 39            metadata.PropertyChangedCallback += OnSpacePropertyChanged;
 40
 41            //Register dependency property
 42            SpaceProperty = DependencyProperty.Register("Space"typeof(int), typeof(SpaceButton),
 43                metadata, ValidateSpaceValue);
 44        }

 45
 46        static bool ValidateSpaceValue(object obj)
 47ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 48            int i = (int)obj;
 49            return i >= 0;
 50        }

 51
 52        //Recall method, when the property change
 53        static void OnSpacePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
 54ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 55            SpaceButton btn = obj as SpaceButton;
 56            btn.Content = btn.SpaceOutText(btn.txt);
 57        }

 58
 59        private string SpaceOutText(string str)
 60ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 61            if (str == null)
 62                return null;
 63
 64            StringBuilder sb = new StringBuilder();
 65            foreach (char ch in str)
 66ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 67                sb.Append(ch + new string(' ', Space));
 68            }

 69            return sb.ToString();
 70        }

 71    }

 72
 73    public class SpaceWindow : Window
 74ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 75        public static readonly DependencyProperty SpaceProperty;
 76        public int Space
 77ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 78ExpandedSubBlockStart.gifContractedSubBlock.gif            set { SetValue(SpaceProperty, value); }
 79ExpandedSubBlockStart.gifContractedSubBlock.gif            get return (int)GetValue(SpaceProperty); }
 80        }

 81
 82        static SpaceWindow()
 83ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 84            FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
 85            metadata.Inherits = true;
 86
 87            //Add owner to SpacePropery and override metadata
 88            SpaceProperty = SpaceButton.SpaceProperty.AddOwner(typeof(SpaceWindow));
 89            SpaceProperty.OverrideMetadata(typeof(SpaceWindow), metadata);
 90        }

 91
 92    }

 93
 94    public class SetSpaceProperty : SpaceWindow
 95ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 96        [STAThread]
 97        public static void Main()
 98ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 99            Application app = new Application();
100            app.Run(new SetSpaceProperty());
101        }

102
103        public SetSpaceProperty()
104ExpandedSubBlockStart.gifContractedSubBlock.gif        {
105            Title = "Set Space property";
106
107            SizeToContent = SizeToContent.WidthAndHeight;
108            ResizeMode = ResizeMode.CanMinimize;
109ExpandedSubBlockStart.gifContractedSubBlock.gif            int[] iSpace = 0,1,2};
110
111            Grid grid = new Grid();
112            Content = grid;
113
114            for (int i = 0; i < 2; i++)
115ExpandedSubBlockStart.gifContractedSubBlock.gif            {
116                RowDefinition row = new RowDefinition();
117                row.Height = GridLength.Auto;
118                grid.RowDefinitions.Add(row);
119            }

120
121            for (int i = 0; i < iSpace.Length; i++)
122ExpandedSubBlockStart.gifContractedSubBlock.gif            {
123                ColumnDefinition col = new ColumnDefinition();
124                col.Width = GridLength.Auto;
125                grid.ColumnDefinitions.Add(col);
126            }

127
128            for (int i = 0; i < iSpace.Length; i++)
129ExpandedSubBlockStart.gifContractedSubBlock.gif            {
130                SpaceButton btn = new SpaceButton();
131                btn.Text = "Set window space to " + iSpace[i];
132                btn.Tag = iSpace[i];
133                btn.HorizontalAlignment = HorizontalAlignment.Center;
134                btn.VerticalAlignment = VerticalAlignment.Center;
135                btn.Click += this.WindowPropertyOnClick;
136                grid.Children.Add(btn);
137                Grid.SetRow(btn, 0);
138                Grid.SetColumn(btn, i);
139
140                btn = new SpaceButton();
141                btn.Text = "Set button spae to " + iSpace[i];
142                btn.Tag = iSpace[i];
143                btn.HorizontalAlignment = HorizontalAlignment.Center;
144                btn.VerticalAlignment = VerticalAlignment.Center;
145                btn.Click += this.ButtonPropertyOnClick;
146                grid.Children.Add(btn);
147                Grid.SetRow(btn, 1);
148                Grid.SetColumn(btn, i);
149
150            }

151        }

152
153        void WindowPropertyOnClick(object sender, RoutedEventArgs args)
154ExpandedSubBlockStart.gifContractedSubBlock.gif        {
155            SpaceButton btn = args.Source as SpaceButton;
156            Space = (int)btn.Tag;
157        }

158
159        void ButtonPropertyOnClick(object sender, RoutedEventArgs args)
160ExpandedSubBlockStart.gifContractedSubBlock.gif        {
161            SpaceButton btn = args.Source as SpaceButton;
162            btn.Space = (int)btn.Tag;
163        }

164
165
166    }

167}

168

[Question]Logical tree, Visual tree, will trace it in the next

 

 

转载于:https://www.cnblogs.com/refeiner/archive/2009/04/18/1437623.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值