C# Avalonia怎么使用依赖属性 Avalonia AvaloniaProperty教程

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

在 Avalonia 中,依赖属性(

AvaloniaProperty
)是实现数据绑定、样式、模板、动画和属性继承等核心功能的基础机制。它不同于 WPF 的
DependencyProperty
,但设计理念相似,使用方式更轻量、更函数式。

什么是 AvaloniaProperty?

AvaloniaProperty
是一个不可变的类型,用于注册和标识 UI 元素上的可绑定、可动画、可继承的属性。它本身不存储值,而是作为“属性描述符”存在,真正的值由
AvaloniaObject
(如
Control
Window
)内部的稀疏存储系统管理。

所有 Avalonia 控件都继承自

AvaloniaObject
,因此天然支持依赖属性。

如何定义和注册一个依赖属性?

使用静态只读字段 +

AvaloniaProperty.Register
方法注册。推荐在类内部声明,并用
public static readonly
修饰。

语法简洁:只需指定属性名、所属类型、默认值(可选)、元数据(如是否继承、是否可动画) 泛型强类型:编译期检查类型安全,无需装箱/拆箱

示例:为自定义控件

MyButton
添加一个
CornerRadius
属性:

public class MyButton : Button
{
    public static readonly AvaloniaProperty<CornerRadius> CornerRadiusProperty =
        AvaloniaProperty.Register<MyButton, CornerRadius>(nameof(CornerRadius), defaultValue: new CornerRadius(4));
<pre class="brush:php;toolbar:false;">public CornerRadius CornerRadius
{
    get => GetValue(CornerRadiusProperty);
    set => SetValue(CornerRadiusProperty, value);
}

}

注意:

GetValue
/
SetValue
AvaloniaObject
提供的基方法,必须成对使用;属性包装器(即 CLR 属性)不是必需的,但强烈建议提供,方便 C# 代码调用和 XAML 绑定。

如何在 XAML 和绑定中使用?

注册后即可像内置属性一样使用:

XAML 中直接设置:
<mybutton cornerradius="8"></mybutton>
支持绑定:
<mybutton cornerradius="{Binding Radius}"></mybutton>
支持样式触发器和模板绑定

若需响应属性变更,可在注册时传入

new AvaloniaPropertyMetadata<t>(default, onChanged)</t>
,其中
onChanged
是一个
Action<avaloniaobject t></avaloniaobject>
委托,接收对象实例、旧值和新值。

public static readonly AvaloniaProperty<string> TitleProperty =
    AvaloniaProperty.Register<MyButton, string>(
        nameof(Title),
        defaultValue: "Default",
        metadata: new AvaloniaPropertyMetadata<string>(
            default,
            (o, _, newValue) => ((MyButton)o).OnTitleChanged(newValue)));
<p>private void OnTitleChanged(string newValue)
{
// 响应逻辑,例如更新内部 TextBlock
}</p>

高级技巧与注意事项

附加属性:用
AvaloniaProperty.RegisterAttached
定义,适用于扩展其他控件行为(如
Grid.Row
),需提供
GetXXX
SetXXX
静态方法
继承属性:通过
AvaloniaPropertyMetadata.Inherits = true
启用,子元素自动继承父级该属性值(如
FontSize
验证回调:注册时可传入
validate
函数(
Func<t bool></t>
),在设值前校验合法性
避免内存泄漏:不要在
onChanged
中捕获外部引用或注册未释放的事件

不复杂但容易忽略:所有依赖属性必须在静态构造函数或类加载时完成注册,不能延迟初始化;且一个属性只能注册一次,重复注册会抛异常。

相关推荐