依赖属性
什么时候需要定义依赖属性
1〉 如果希望属性可以在Style中设定
2〉 如果希望属性可以数据绑定
3〉 如果希望属性可以由动态资源(DynamicResource)设定
4〉 如果希望从父元素那里获得值
5〉 如果希望属性可以设置动画
6〉 如果希望属性在被修改时能够检测值得有效性,修改后回调
7〉 如果希望使用已有的依赖属性(Metadata override)
功能:
1〉 资源
2〉 数据邦定
3〉 风格
4〉 动画
5〉 Metadata重载
6〉 属性值继承
依赖属性的示例
public static readonly DependencyProperty IsSpinningProperty =
DependencyProperty.Register(
...
);
public bool IsSpinning
{
get { return (bool)GetValue(IsSpinningProperty); }
set { SetValue(IsSpinningProperty, value); }
}
资源
依赖属性的值可以通过引用一个资源来设置。资源一般放在一个页面(Page/Window)的根节点下的子节点。或者放在应用程序XMAL文件中。
示例:
资源的定义
<DockPanel.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</DockPanel.Resources>
资源的使用
<Button Background=”{DynamicResource MyBrush}” Content=”example”>
数据绑定
数据绑定可以实现在运行时通过获取数据源的值来改变具有数据绑定的属性值
下面的示例将设置Button的Content属性的绑定,数据绑定到xml文件
XML文件如下:
<?xml version="1.0" encoding="utf-8" ?>
<
DataPointList
>
<
DemoDataSource
>
<
datapoint2
/>
<
datapoint3
/>
</
DemoDataSource
>
</
DataPointList
>
<StackPanel Canvas.Top=”50” DataContext=”{Binding Source=”{StaticResource XmlTeamsSource}}”}”>
<Button Content=”{Binding XPath=”
DataPointList/DemoDataSource/datapoint2”}”>
风格(Styles)
风格一般用来改变UI显示
示例:
定义,
<Style x:Key=”GreenButtonStyle”>
<Setter Property=”Control.Background” Value=”Green”/>
</Style>
使用:
<Button Style=”{StaticResource GreenButtonStyle}”> this is Green</Button>
动画
Metadata 重载
通过在子类中重载父类中注册过的依赖属性可以改变该依赖属性的行为。重载一个Metadata不需要 重新实现它。
示例如下:
Public class SpinnerControl : ItemsControl
{
Static SpinnerControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
Typeof(SpinnerControl),
New FrameworkPropertyMetadata(typeof(SpinnerControl))
);
}
}
依赖属性的实现
注册
如果希望属性成为依赖属性,你必须注册该属性到一个由属性系统维持的表中,并为其指定一个唯一标示。
示例:
public static readonly DependencyProperty AquariumGraphicProperty = DependencyProperty.Register(
"AquariumGraphic",
typeof(Uri),
typeof(AquariumObject),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnUriChanged)
)
);
// Wrapper
public Uri AquariumGraphic
{
get { return (Uri)GetValue(AquariumGraphicProperty); }
set { SetValue(AquariumGraphicProperty, value); }
}
Wrapper的Identity与Register的第一个参数最好一致。
Property Metadata
当注册依赖属性时,将通过属性系统创建一个metadata object来保存属性特征。可以在其中设置属性的缺省值,回调函数等。
有两种Metadata
1> FrameworkPropertyMetadata
一般用在继承自FrameworkElement的类中,它提供比PropertyMetadata更多的选项来初始化属性,示例如上。
2> PropertyMetadata
一般初始化属性的缺省值和回调函数
示例如下:
public DateTime Time
{
get
{
return (DateTime)GetValue(TimeProperty);
}
private set
{
SetValue(TimeProperty, value);
}
}
public static DependencyProperty TimeProperty = DependencyProperty.Register(
"Time",
typeof(DateTime),
typeof(MyClock),
new PropertyMetadata(DateTime.Now, new PropertyChangedCallback(OnDateTimeInvalidated)));
private static void OnDateTimeInvalidated(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyClock clock = (MyClock)d;
DateTime oldValue = (DateTime)e.OldValue;
DateTime newValue = (DateTime)e.NewValue;
clock.OnDateTimeChanged(oldValue, newValue);
}