Wpf 简明教程
WPF - Dependency Properties
在 WPF 应用程序中,依赖属性是一种扩展 CLR 属性的特定类型属性。它利用了 WPF 属性系统中可用的特定功能。
In WPF applications, dependency property is a specific type of property which extends the CLR property. It takes the advantage of specific functionalities available in the WPF property system.
定义依赖属性的类必须继承自 DependencyObject 类。XAML 中使用的许多 UI 控件类都继承自 DependencyObject 类并且它们支持依赖属性,例如,Button 类支持 IsMouseOver 依赖属性。
A class which defines a dependency property must be inherited from the DependencyObject class. Many of the UI controls class which are used in XAML are derived from the DependencyObject class and they support dependency properties, e.g. Button class supports the IsMouseOver dependency property.
以下 XAML 代码创建一个具有某些属性的按钮。
The following XAML code creates a button with some properties.
<Window x:Class = "WPFDependencyProperty.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local = "clr-namespace:WPFDependencyProperty"
Title = "MainWindow" Height = "350" Width = "604">
<Grid>
<Button Height = "40" Width = "175" Margin = "10" Content = "Dependency Property">
<Button.Style>
<Style TargetType = "{x:Type Button}">
<Style.Triggers>
<Trigger Property = "IsMouseOver" Value = "True">
<Setter Property = "Foreground" Value = "Red" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>
XAML 中的 x:Type 标记扩展具有类似 C# 中 typeof() 的功能。当指定将采用对象类型的属性时使用此功能,例如 <Style TargetType = "{x:Type Button}">。
The x:Type markup extension in XAML has a similar functionality like typeof() in C#. It is used when attributes are specified which take the type of the object such as <Style TargetType = "{x:Type Button}">
当编译并执行上述代码时,你将获得以下 MainWindow 。当鼠标位于按钮上方时,它会更改按钮的前景色。当鼠标离开按钮时,它会变回其原始颜色。
When the above code is compiled and executed, you would get the following MainWindow. When the mouse is over the button, it will change the foreground color of a button. When the mouse leaves the button, it changes back to its original color.

Why We Need Dependency Properties
当你将其用于你的应用程序时,依赖属性会为你提供各种好处。依赖属性在以下情况下可用于 CLR 属性:
Dependency property gives you all kinds of benefits when you use it in your application. Dependency Property can used over a CLR property in the following scenarios −
-
If you want to set the style
-
If you want data binding
-
If you want to set with a resource (a static or a dynamic resource)
-
If you want to support animation
基本上,依赖属性提供了许多使用 CLR 属性无法获得的功能。
Basically, Dependency Properties offer a lot of functionalities that you won’t get by using a CLR property.
dependency properties 和其他 CLR properties 之间的主要区别如下所列:
The main difference between dependency properties and other CLR properties are listed below −
-
CLR properties can directly read/write from the private member of a class by using getter and setter. In contrast, dependency properties are not stored in local object.
-
Dependency properties are stored in a dictionary of key/value pairs which is provided by the DependencyObject class. It also saves a lot of memory because it stores the property when changed. It can be bound in XAML as well.
Custom Dependency Properties
在 .NET framework 中,还可以定义自定义依赖属性。请按照以下步骤在 C# 中定义自定义依赖属性。
In .NET framework, custom dependency properties can also be defined. Follow the steps given below to define custom dependency property in C#.
-
Declare and register your dependency property with system call register.
-
Provide the setter and getter for the property.
-
Define a static handler which will handle any changes that occur globally
-
Define an instance handler which will handle any changes that occur to that particular instance.
以下 C# 代码定义了一个依赖属性来设置用户控件的 SetText 属性。
The following C# code defines a dependency property to set the SetText property of the user control.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication3 {
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl {
public UserControl1() {
InitializeComponent();
}
public static readonly DependencyProperty SetTextProperty =
DependencyProperty.Register("SetText", typeof(string), typeof(UserControl1), new
PropertyMetadata("", new PropertyChangedCallback(OnSetTextChanged)));
public string SetText {
get { return (string)GetValue(SetTextProperty); }
set { SetValue(SetTextProperty, value); }
}
private static void OnSetTextChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e) {
UserControl1 UserControl1Control = d as UserControl1;
UserControl1Control.OnSetTextChanged(e);
}
private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) {
tbTest.Text = e.NewValue.ToString();
}
}
}
这是 TextBlock 被定义为用户控件的 XAML 文件,并通过 SetText 依赖属性将 Text 属性分配给它。
Here is the XAML file in which the TextBlock is defined as a user control and the Text property will be assigned to it by the SetText dependency property.
下面的 XAML 代码创建了一个用户控件并初始化了它的 SetText 依赖属性。
The following XAML code creates a user control and initializes its SetText dependency property.
<Window x:Class = "WpfApplication3.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views = "clr-namespace:WpfApplication3"
Title = "MainWindow" Height = "350" Width = "604">
<Grid>
<views:UserControl1 SetText = "Hellow World"/>
</Grid>
</Window>
让我们运行该应用程序。你可以立即观察到在我们的 MainWindow 中,用户控件的依赖属性已经成功用作 Text。
Let’s run this application. You can immediately observe that in our MainWindow, the dependency property for user control has been successfully used as a Text.
