学习SL/WPF,Dependency Properties(依赖
属性)是
一个全新(陌生)但又无法回避的概念。
先回想一下传统的
属性(Property):通常我们读取或赋值
一个属性时,实际上是在对
属性背后的某个私有成员进行读写。那么随着对象的
属性越来越多,再
加上从对象派生出去的子对象,子对象再生出“孙子”对象......最终的对象运行实例中会有大量的私有成员,而每私有成员都要分配内存,占用一定的资源。
但反过来想想,通常我们在使用
一个控件/对象时,往往只用到了某几个
属性,大部分
属性(有时候甚至达到90%以上)都是采用的
默认值(或者也可以理解为没有用到),这对于WPF/SL来说无疑是一种极大的
性能损耗。
所以在此背景之下,DP(Dependency Properties的简称)就出现了,我们再回想一下静态(stati
C)方法或成员,静态成员/
方法的
调用不依赖于实例,它是class级别的,不管这个类有多少个实例,静态成员在内存中只占一份,这正是我们所要的!
所有具备依赖
属性的对象,都是继承自DependencyOb
ject,DependencyOb
ject中有
一个"字典"存储区用来存放依赖
属性,而且都是用static方式读取的,所以你现在应该想明白了:为啥不能直接用txt.Left = xxx来直接赋值,而必须用txt.
SETVALue(Canva
s.Left,xx
X)来处理,
因为Static成员是实例无法
调用的。
DP的优点:
(2)直接继承上级的
属性值(这里也解释了为什么上级控件对下级控件
自动布局,因为下级控件
自动继承了上级控件的相关
属性值)
(3)
自动实现了“变化
通知”(dp有内置的Change Notification回调接口)
这张图描述了GetValue与
SETVALue的内部读取策略.
(1)先建
一个Silverlight User Control,取名为MyControl
xaml部分:
代码
@H_
607_131@
<
UserControl
x:Class
="DPstudy.MyControl"
xmlns
="http://scheR_476_11845@as.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://scheR_476_11845@as.microsoft.com/winfx/2006/xaml"
>
Border
CornerRadius
="5"
BorderThickness
="3"
BorderBrush
="#FFEF410D"
Width
="300"
Height
="40"
Margin
TextBlock
x:Name
="txt"
text
=""
VerticalAlignment
="Center"
HorizontalAlignment
="Center"
></
TextBlock
</
Border
UserControl
>
CS部分:(技巧:vs2008中,只要键入propdp,再连敲二次Tab键,vs就会自动添加一个依赖属性的代码模板)
代码
using
System.Windows;
System.Windows.Controls;
namespace
DPstudy
{
public
partial
class
MyControl : UserControl
{
static
readonly
DependencyProperty messageProperty
=
DependencyProperty.Register(
"
message
"
,
typeof
(
String
),0)">(MyControl),255)">new
PropertyMetadata(
message的默认值
PropertyChangedCallBACk(OnmessagePropertyChanged)));
message
{
get
{
return
(
)
GetValue
(messageProperty); }
set
{
SETVALue
(messageProperty, value); }
}
///
<sumMary>
message变化时的通知处理
</sumMary>
<param NAME="d"></param>
<param NAME="e"></param>
private
void
OnmessagePropertyChanged
(DependencyObject d, DependencyPropertyChangedEventArgs E)
{
MyControl ctl
=
d
as
MyControl;
ctl.txt.Text
d.GetValue(MyControl.messageProperty).ToString();
}
MyControl()
{
initializeComponent();
this
.Loaded
+=
routedEventHandler(MyControl_Loaded);
}
MyControl_Loaded(
object
sender, routedEventArgs E)
{
.txt.Text
message;
//
初始加载时,显示message的初始值
}
}
}
这里我们定义了一个message的String类型依赖属性,和普通属性的区别是:必须使用DependencyProperty.Register来注册该属性,而且“属性命名”要以Property为后缀;另外在读取时,必须调用SETVALue/GetValue静态方法来读取其值,最后我们还可以添加一个"属性值变化时的"回调处理。
(2)将MyControl放到MainPage.xaml中小试牛刀
MainPage.Xaml内容如下:
代码
="DPstudy.MainPage"
xmlns:d
="http://scheR_476_11845@as.microsoft.com/expression/blend/2008"
xmlns:mc
="http://scheR_476_11845@as.openxmlformats.org/markup-compatibility/2006"
xmlns:l
="clr-namespace:DPstudy"
mc:Ignorable
="d"
d:DesignWidth
="640"
d:DesignHeight
="480"
StackPanel
="LayoutRoot"
<
l:MyControl
x:Name
="myctl"
></
l:MyControl
Button
Click
="Button_Click"
Content
="改变message属性值"
="130"
Button
StackPanel
复制代码
MainPage.Xaml.cs内容如下:
代码
System.Windows.Controls;
MainPage : UserControl
{
MainPage()
{
initializeComponent();
}
Button_Click(
:12px; line-height:1.5; color:rgb(0, routedEventArgs E)
{
myctl.SETVALue(MyControl.messageProperty,
新值
);
}
}
}
运行后,点击按钮将改变MyControl控件的message属性值,同时MyControl中的文本控件的文字也将变成"新值"
转载请注明来自菩提树下的杨过
文中源
文件代码:
DPStudy.rar