在 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中捕获外部引用或注册未释放的事件
不复杂但容易忽略:所有依赖属性必须在静态构造函数或类加载时完成注册,不能延迟初始化;且一个属性只能注册一次,重复注册会抛异常。
