Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展common languageruntime (CLR) 属性的功能。 这些服务通常统称为 WPF 属性系统。 由 WPF 属性系统支持的属性称为依赖项属性。依赖属性是一种可以自己没有值,并能通过使用Binding从数据源获得值的属性(通俗的讲,就是依赖在别的属性上)。
- 依赖属性支持CLR属性
- 依赖项属性的用途在于提供一种方法来基于其他输入的值计算属性值。 这些其他输入可以包括系统属性(如主题和用户首选项)、实时属性确定机制(如数据绑定和动画/演示图板)、重用模板(如资源和样式)或者通过与元素树中其他元素的父子关系来公开的值。 另外,可以通过实现依赖项属性来提供独立验证、默认值、监视其他属性的更改的回调以及可以基于可能的运行时信息来强制指定属性值的系统。 派生类还可以通过重写依赖项属性元数据(而不是重写现有属性的实际实现或者创建新属性)来更改现有属性的某些具体特征。
- 如何区分依赖属性与CLR属性:在属性的MSDN帮助文档中,假如该属性为依赖属性,在属性说明中会有依赖项属性信息说明,如下(TextBox.Text):
-
定义依赖属性
例子:书写MyTextBox控件,继承自TextBox。给MyTextBox添加MyText依赖属性:
//依赖属性名称MyTextProperty //依赖属性标识符MyText public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText",typeof(string),typeof(MyTextBox)); //依赖属性的CLR属性包装 public string MyText { get { return (string)GetValue(MyTextProperty); } set { SetValue(MyTextProperty,value); } }
Register 方法 参数说明
name |
|
propertyType |
属性的类型。 |
ownerType |
正注册依赖项对象的所有者类型。 |
typeMetadata |
依赖项对象的属性元数据。 |
validateValueCallback |
对回调的引用,除了典型的类型验证之外,该引用还应执行依赖项对象值的任何自定义验证。 |
-
资源
依赖项属性值可以通过引用资源来设置。
<Window.Resources> <!--资源--> <sys:String x:Key="text">text_Resources</sys:String> </Window.Resources> <Grid> <!--Text属性引用资源--> <MyTextBox:MyTextBox x:Name="myTextBox" HorizontalAlignment="Left" Height="44" Margin="70,81,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="213" Text="{DynamicResource text}"/> </Grid>
-
数据绑定
绑定注意点:(1) 绑定必须指定数据上下文DataContext;
(2)绑定源必须是属性,变量无效;
(3)绑定源必须是公开的Public;
(4)如果绑定源更改时,控件绑定目标依赖属性需要跟随更改,那么绑定源必须继承INotifyPropertyChanged接口。
示例(TextBox.Text依赖属性绑定到MainWindow类中的TextForBinding属性):
public string TextForBinding { get; set; }
继承INotifyPropertyChanged接口的写法:
public partial class MainWindow : Window,INotifyPropertyChanged { public string TextForBinding { get; set; } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string info) { PropertyChangedEventHandler handler =PropertyChanged; if (handler != null) { handler(this,new PropertyChangedEventArgs(info)); } } }
XAML中:
Text="{Binding TextForBinding}"
-
样式
示例(写一个红色前景色的样式并引用):
书写样式:
<Window.Resources> <!--资源--> <sys:String x:Key="text">text_Resources</sys:String> <Style x:Key="MyStyle" TargetType="MyTextBox:MyTextBox"> <Setter Property="Foreground" Value="Red" /> </Style> </Window.Resources>
引用样式
Style="{DynamicResource MyStyle}"
-
动画
示例(鼠标进入文本框时文本框变宽):
<MyTextBox:MyTextBox x:Name="myTextBox" HorizontalAlignment="Left" Height="44" Margin="70,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="213" Text="{Binding TextForBinding}" Style="{DynamicResource MyStyle}"> <MyTextBox:MyTextBox.Triggers> <EventTrigger RoutedEvent="TextBox.MouseEnter"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="myTextBox" Storyboard.TargetProperty="Width" By="100" Duration="0:0:2"/> </Storyboard> </BeginStoryboard> </EventTrigger> </MyTextBox:MyTextBox.Triggers> </MyTextBox:MyTextBox>
鼠标离开时的没写,大家可以自己写下。
-
元数据重写
在依赖属性进阶中说明。
-
属性值继承
元素可以从其在对象树中的父级继承依赖项属性的值。
在功能2的数据绑定中,给窗体绑定数据上下文DataContext,代码如下:
public partial class MainWindow : Window,INotifyPropertyChanged { public MainWindow() { InitializeComponent(); TextForBinding = "TextForBinding"; this.DataContext = this; } … }
子对象(MyTextBox)中的为指定数据上下文即可进行数据绑定。
-
WPF设计器集成
自定义控件具有实现为依赖项属性的属性,则它将收到相应的适用于 Visual Studio 的 WPF 设计器支持。
<MyTextBox:MyTextBox x:Name="myTextBox" MyText="WPF 设计器集成"/>
-
依赖属性优先级
最高优先级将最先列出,顺序如下:
- 属性系统强制转换。
- 活动动画或具有 Hold 行为的动画。为了获得任何实用效果,属性的动画必须优先于基(未动画)值,即使该值是在本地设置的情况下也将如此。
- 本地值。本地值可以通过“包装”属性的便利性进行设置,这也相当于在 XAML 中设置特性或属性元素,或者使用特定实例的属性调用SetValueAPI。如果您使用绑定或资源来设置本地值,则每个值都按照直接设置值的优先级顺序来应用。
- TemplatedParent 模板属性。如果元素是作为模板(ControlTemplate或DataTemplate)的一部分创建的,则具有TemplatedParent。在模板中,按以下优先级顺序应用:
- 来自TemplatedParent模板的触发器。
- TemplatedParent模板中的属性集。(通常通过 XAML特性进行设置。)
- 隐式样式。仅应用于Style属性。Style属性是由任何样式资源通过与其类型匹配的键来填充的。该样式资源必须存在于页面或应用程序中;查找隐式样式资源不会进入到主题中。
- 样式触发器。来自页面或应用程序上的样式中的触发器。(这些样式可以是显式或隐式样式,但不是来自优先级较低的默认样式。)
- 模板触发器。来自样式中的模板或者直接应用的模板的任何触发器。
- 样式 Setter。来自页面或应用程序的样式中的Setter的值。
- 默认(主题)样式。在默认样式中,按以下优先级顺序应用:
- 继承。有几个依赖项属性从父元素向子元素继承值,因此不需要在应用程序中的每个元素上专门设置这些属性。
- 来自依赖项属性元数据的默认值。任何给定的依赖项属性都具有一个默认值,它由该特定属性的属性系统注册来确定。而且,继承依赖项属性的派生类具有按照类型重写该元数据(包括默认值)的选项。因为继承是在默认值之前检查的,所以对于继承的属性,父元素的默认值优先于子元素。因此,如果任何地方都没有设置可继承的属性,将使用在根元素或父元素中指定的默认值,而不是子元素的默认值。
参考内容:http://msdn.microsoft.com/zh-cn/library/ms752914(v=vs.100).aspx
作者:FoolRabbit
出处:http://blog.csdn.net/rabbitsoft_1987 欢迎任何形式的转载,未经作者同意,请保留此段声明!