WPF中的DependencyProperty怎么用 WPF依赖属性创建与使用

来源:这里教程网 时间:2026-02-21 17:34:14 作者:

WPF 中的 DependencyProperty 是实现数据绑定、样式、模板、动画、属性继承等核心功能的基础。它不是普通 .NET 属性,而是一种由 WPF 属性系统管理的特殊属性,必须通过静态注册方式声明,并配合

GetValue
/
SetValue
方法访问。

依赖属性怎么创建

创建依赖属性需三步:定义静态只读字段、在类中注册、提供标准包装属性(可选但强烈推荐)。

使用
DependencyProperty.Register
注册,传入属性名、类型、所属类类型、可选元数据(如默认值、回调)
注册返回的
DependencyProperty
对象必须赋给
public static readonly
字段
为方便 XAML 和 C# 代码调用,建议提供同名的 .NET 属性包装器,内部调用
GetValue
/
SetValue

示例(在自定义控件

MyButton
中定义
CornerRadius
依赖属性):

public class MyButton : Control
{
    // 1. 静态只读字段
    public static readonly DependencyProperty CornerRadiusProperty =
        DependencyProperty.Register(
            nameof(CornerRadius),
            typeof(double),
            typeof(MyButton),
            new PropertyMetadata(0.0)); // 默认值为 0.0
<pre class="brush:php;toolbar:false;">// 2. 包装属性(非必需但实用)
public double CornerRadius
{
    get => (double)GetValue(CornerRadiusProperty);
    set => SetValue(CornerRadiusProperty, value);
}

}

依赖属性怎么在 XAML 中使用

XAML 中使用依赖属性和普通属性写法一致,只要该属性是公开的包装属性或直接支持属性语法即可。

直接赋值:
<mybutton cornerradius="8"></mybutton>
绑定表达式:
<mybutton cornerradius="{Binding Radius}"></mybutton>
动画目标:
<doubleanimation to="12" storyboard.targetproperty="CornerRadius"></doubleanimation>
样式 Setter:
<setter property="CornerRadius" value="6"></setter>

注意:XAML 实际解析时,会通过反射找到

CornerRadiusProperty
字段并调用
SetValue
,所以包装属性名必须与字段名(去掉
Property
后缀)严格匹配。

依赖属性的常用元数据与回调

注册时传入的

PropertyMetadata
可指定默认值、属性变更回调、属性值强制回调等,增强行为控制。

DefaultValue
:影响属性未显式设置时的表现(如不触发样式触发器)
PropertyChangedCallback
:值改变后触发,接收 old/new 值,适合同步更新内部状态
CoerceValueCallback
:在值被设入前“修正”它(例如限制范围、对齐步长)
FrameworkPropertyMetadata
:额外标记(如是否参与布局、是否可继承、是否影响渲染),常用于 UI 控件

例如限制

CornerRadius
不小于 0:

new FrameworkPropertyMetadata(
    0.0,
    OnCornerRadiusChanged,
    CoerceCornerRadius)
<p>private static object CoerceCornerRadius(DependencyObject d, object baseValue)
=> Math.Max(0.0, (double)baseValue);</p><p>private static void OnCornerRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var btn = (MyButton)d;
btn.InvalidateVisual(); // 触发重绘
}</p>

依赖属性的注意事项

依赖属性能力强大,但也有明确约束和易错点:

只能在
DependencyObject
派生类中定义(如
UIElement
FrameworkElement
Control
不能在构造函数中通过
SetValue
初始化(应改用元数据默认值或在
OnInitialized
中设)
不要在包装属性的 getter/setter 中加复杂逻辑或异常抛出——它们可能被频繁调用,且部分场景(如模板实例化)会绕过包装器 多个依赖属性共用一个回调方法时,务必用
d as XXX
安全转换,避免类型错误

基本上就这些。掌握注册模式、理解包装器作用、善用元数据回调,就能稳妥地扩展 WPF 控件行为。

相关推荐