最常用轻量方式是继承UserControl,适合封装已有控件;需完全控制模板、支持主题切换则应继承TemplatedControl;属性用AvaloniaProperty注册,使用需注意DefaultStyleKey和Generic.xaml路径约定。

从 UserControl 开始自定义控件
最常用也最轻量的方式是继承 UserControl,适合封装一组已有控件并暴露少量属性和命令。新建一个 XAML 文件(如 MyButton.xaml),对应后台类继承 UserControl:
- 在 XAML 中写布局(比如一个 Border 包着 TextBlock 和 Icon)
- 后台类中用
public static readonly StyledProperty定义可绑定的属性TextProperty = AvaloniaProperty.Register (...) - 通过
AddOwner或直接在 XAML 中用{Binding $parent[MyButton].Text}关联逻辑
创建真正可复用的 TemplatedControl
如果需要完全控制模板、支持主题切换、响应样式变更,应继承 TemplatedControl(类似 WPF 的 Control)。它不带默认 XAML,所有 UI 都由 ControlTemplate 提供:
- 定义类时继承
TemplatedControl,并在静态构造函数中调用DefaultStyleKeyProperty.OverrideMetadata - 在
Themes/Generic.xaml中为该类型写默认模板,用TemplateBinding绑定到控件属性 - 重写
OnApplyTemplate()获取模板中的命名元素(如var part = this.GetTemplateChild("PART_Icon") as Image;)
添加依赖属性与路由事件
Avalonia 的属性系统基于 AvaloniaProperty,不是 .NET 的普通属性:
- 声明属性:用
StyledProperty.Register ("Name", defaultValue) - 提供 CLR 封装器(get/set 调用
GetValue/SetValue),VS 可用代码片段avprop快速生成 - 要支持命令或交互反馈,可定义
RoutedCommand或用RoutedEvent发布自定义事件.Register
在项目中使用和样式化
自定义控件写完后,需在使用处声明 XML 命名空间,并像内置控件一样使用:
- XAML 中添加命名空间:
xmlns:local="using:MyApp.Controls" - 直接写
- 可通过
Style重写模板,或在Generic.xaml中统一设置默认样式;支持:pointerover、:pressed等伪类
基本上就这些。不复杂但容易忽略的是 DefaultStyleKey 设置和 Generic.xaml 的路径约定——这两处错一个,模板就不会自动加载。










