简介
Dependency Property: 它们依赖一些其他的property和外在的影响,引起自身的变化.
如: WPF框架的编程经常和界面打交道,经常遇到的一个情况是某个属性的值的变化会影响到多个其他对象。比如当一个Button的改变大小超过了它的容器,他的容器应该自动调整大小。于是我们考虑在每个属性的set方法中触发一些事件,但很快我们发现现有的功能很难满足我们的需求,至少不能简洁漂亮的满足这些需求。
定义示例: public static readonly DependencyProperty FontSizePropery;
1.简单的element tree
通过简单的例子来理解"沿袭"(不能说是继承)
窗口构造函数将Font size 初使化为16设备无关的单位. 所有的BUTTON都会沿袭这个设置(都是WINDOW的孩子)
Code
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Windows;
5
using System.Windows.Controls;
6
using System.Windows.Documents;
7![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
8
namespace DockAndGrid
9![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
10
public class SetFontSizeProperty : Window
11![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
12
[STAThread]
13
public static void Main()
14![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
15
Application app = new Application();
16
app.Run(new SetFontSizeProperty());
17
}
18![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
public SetFontSizeProperty()
20![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
21
Title = "Set size property";
22
SizeToContent = SizeToContent.WidthAndHeight;
23
ResizeMode = ResizeMode.CanMinimize;
24
FontSize = 16;
25![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Double[] fntsizes =
{ 8,16,32};
26![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
Grid grid = new Grid();
28
Content = grid;
29![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
for (int i = 0; i < 2; i++)
31![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.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++)
37![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
38
ColumnDefinition col = new ColumnDefinition();
39
col.Width = GridLength.Auto;
40
grid.ColumnDefinitions.Add(col);
41
}
42![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
43
for (int i = 0; i < fntsizes.Length; i++)
44![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.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![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
67
void WindowFontSizeOnClick(object sender, RoutedEventArgs args)
68![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
69
Button btn = args.Source as Button;
70
FontSize = (double)btn.Tag;
71
}
72![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
73
void ButtonFontSizeOnClick(object sender, RoutedEventArgs args)
74![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
75
Button btn = args.Source as Button;
76
btn.FontSize = (double)btn.Tag;
77
}
78![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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维持目前的值,且处理所有的日常事务.
完整示例:
Code
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Windows;
6
using System.Windows.Controls;
7
using System.Windows.Media;
8
using System.Windows.Input;
9![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
10
namespace DependencyProperty1
11![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
12
class SpaceButton : Button
13![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
14
string txt;
15
public string Text
16![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
17![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return txt; }
18
set
19![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
20
txt = value;
21
Content = SpaceOutText(txt);
22
}
23
}
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
public static readonly DependencyProperty SpaceProperty;
26
public int Space
27![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
28![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ SetValue(SpaceProperty, value); }
29![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return (int)GetValue(SpaceProperty); }
30
}
31![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
32
static SpaceButton()
33![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.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![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
41
//Register dependency property
42
SpaceProperty = DependencyProperty.Register("Space", typeof(int), typeof(SpaceButton),
43
metadata, ValidateSpaceValue);
44
}
45![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
46
static bool ValidateSpaceValue(object obj)
47![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
48
int i = (int)obj;
49
return i >= 0;
50
}
51![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
52
//Recall method, when the property change
53
static void OnSpacePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
54![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
55
SpaceButton btn = obj as SpaceButton;
56
btn.Content = btn.SpaceOutText(btn.txt);
57
}
58![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
59
private string SpaceOutText(string str)
60![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
61
if (str == null)
62
return null;
63![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
64
StringBuilder sb = new StringBuilder();
65
foreach (char ch in str)
66![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
67
sb.Append(ch + new string(' ', Space));
68
}
69
return sb.ToString();
70
}
71
}
72![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
73
public class SpaceWindow : Window
74![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
75
public static readonly DependencyProperty SpaceProperty;
76
public int Space
77![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
78![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ SetValue(SpaceProperty, value); }
79![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return (int)GetValue(SpaceProperty); }
80
}
81![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
82
static SpaceWindow()
83![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
84
FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
85
metadata.Inherits = true;
86![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
87
//Add owner to SpacePropery and override metadata
88
SpaceProperty = SpaceButton.SpaceProperty.AddOwner(typeof(SpaceWindow));
89
SpaceProperty.OverrideMetadata(typeof(SpaceWindow), metadata);
90
}
91![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
92
}
93![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
94
public class SetSpaceProperty : SpaceWindow
95![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
96
[STAThread]
97
public static void Main()
98![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
99
Application app = new Application();
100
app.Run(new SetSpaceProperty());
101
}
102![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
103
public SetSpaceProperty()
104![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
105
Title = "Set Space property";
106![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
107
SizeToContent = SizeToContent.WidthAndHeight;
108
ResizeMode = ResizeMode.CanMinimize;
109![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
int[] iSpace =
{ 0,1,2};
110![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
111
Grid grid = new Grid();
112
Content = grid;
113![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
114
for (int i = 0; i < 2; i++)
115![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
116
RowDefinition row = new RowDefinition();
117
row.Height = GridLength.Auto;
118
grid.RowDefinitions.Add(row);
119
}
120![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
121
for (int i = 0; i < iSpace.Length; i++)
122![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
123
ColumnDefinition col = new ColumnDefinition();
124
col.Width = GridLength.Auto;
125
grid.ColumnDefinitions.Add(col);
126
}
127![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
128
for (int i = 0; i < iSpace.Length; i++)
129![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.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![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
150
}
151
}
152![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
153
void WindowPropertyOnClick(object sender, RoutedEventArgs args)
154![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
155
SpaceButton btn = args.Source as SpaceButton;
156
Space = (int)btn.Tag;
157
}
158![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
159
void ButtonPropertyOnClick(object sender, RoutedEventArgs args)
160![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
161
SpaceButton btn = args.Source as SpaceButton;
162
btn.Space = (int)btn.Tag;
163
}
164![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
165![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
166
}
167
}
168
[Question]Logical tree, Visual tree, will trace it in the next