Avalonia UI
首页支持GitHub 仓库English Doc
  • 👋欢迎
  • 文档
    • ⚡快速开始
      • IDE 支持
        • JetBrains Rider 设置
      • 使用 Avalonia 开发
        • Model-View-ViewModel 模式(MVVM)
        • 控件和布局
        • 数据绑定
        • 图像和动画
      • Windows
      • UserControls
      • 资产
      • 开发者工具
      • 错误和警告日志
      • 未处理的异常
      • 应用生命周期
    • 🔁数据绑定
      • 数据上下文
      • 变化通知
      • 绑定
      • 编译绑定
      • 与控件绑定
      • 转换绑定值
      • 绑定到命令
      • 绑定到任务和可观察对象
      • 使用代码进行绑定
      • 在控件模板中实现绑定
      • 绑定Classes
      • 创建和绑定到附加属性
      • Data Validation
    • 🎨样式
      • 样式
      • 选择器
      • 资源
      • 疑难解答
    • 🧰控件
      • AutoCompleteBox
      • Border
      • Buttons
        • Button
        • RepeatButton
        • RadioButton
        • ToggleButton
        • ButtonSpinner
        • SplitButton
        • ToggleSplitButton
      • Calendar
      • Canvas
      • Carousel
      • CheckBox
      • ComboBox
      • ContentControl
      • ContextMenu
      • Decorator
      • DataGrid
        • DataGridColumns
      • DatePicker
      • DockPanel
      • Expander
      • Flyouts
      • Grid
      • GridSplitter
      • Image
      • ItemsControl
      • ItemsRepeater
      • LayoutTransformControl
      • ListBox
      • MaskedTextBox
      • Menu
      • NativeMenu
      • NumericUpDown
      • Panel
      • ProgressBar
      • RelativePanel
      • ScrollBar
      • ScrollViewer
      • Separator
      • Slider
      • SplitView
      • StackPanel
      • TabControl
      • TabStrip
      • TextBlock
      • TrayIcon
      • TreeDataGrid
        • Creating a Hierarchical TreeDataGrid
        • Creating a Flat TreeDataGrid
        • TreeDataGrid column types
      • TimePicker
      • TextBox
      • ToolTip
      • TreeView
      • TransitioningContentControl
      • UserControl
      • Viewbox
      • Window
      • WrapPanel
    • 📚模板
      • 数据模板
      • 在代码中创建数据模板
      • 实现 IDataTemplate 接口
    • ✏️自定义控件
      • 控件类别
      • 定义属性
    • 🖱️输入
      • 路由事件
      • 剪贴板
      • 鼠标与触控设备
      • 快捷键
    • 🔑动画
      • 关键帧动画
      • 过渡
      • 页面过渡
    • 📐布局
      • 面板概述
      • Alignment、Margin 和 Padding
      • 创建自定义面板
    • 📦发布/分发
      • macOS
  • API 参考
    • 🗒️命名空间
      • Avalonia
      • Avalonia.Animation
        • Avalonia.Animation.Easings
        • Avalonia.Animation.Animators
      • Avalonia.Collections
      • Avalonia.Controls
      • Avalonia.Data
        • Avalonia.Data.Core.Plugins
        • Avalonia.Data.Core
        • Avalonia.Data.Converters
      • Avalonia.Diagnostics
      • Avalonia.Dialogs
  • 指南
    • 🐣基础
      • XAML 介绍
      • Code-behind
      • MVVM 架构
      • 在UI线程上操作
    • 🤿深入
      • 在树莓派上运行你的应用
      • 在树莓派上运行你的应用(使用Raspbian Lite)
      • ReactiveUI
        • 视图激活机制
        • 路由
        • 数据持久化
        • 绑定到 Sorted/Filtered 数据
    • 👩‍💻👩💻 开发人员指南
      • 🏭从源代码中构建 Avalonia
      • Avalonia 与 WPF 和 UWP 之间的比较
      • Debugging Previewer
      • Debugging the XAML compiler
      • macOS 开发
      • Release Process
      • 维护稳定的分支
  • 教程
    • 📋待办事项应用
    • 📻音乐商店应用
    • 🕸️在浏览器中运行
    • 📱为移动设备开发
  • 杂项
    • 👪社区
    • 🖥️WPF 开发者建议
    • 📋正在使用 Avalonia 的项目
    • ❔常见问题
由 GitBook 提供支持
在本页
  • 订阅对属性的更改
  • 绑定到可观察对象
  • 在对象初始值设定项中设置绑定
  • 转换绑定值
  • 使用代码中的XAML绑定
  • 订阅任意对象的属性
  • 绑定到INotifyPropertyChanged对象

这有帮助吗?

在GitHub上编辑
  1. 文档
  2. 数据绑定

使用代码进行绑定

Avalonia中的代码绑定与WPF/UWP的工作方式有些不同。在低级别上,Avalonia的绑定系统基于Reactive ExtensionsIObservable,然后由XAML绑定构建(也可以在代码中实例化)。

订阅对属性的更改

您可以通过调用GetObservable方法订阅对属性的更改。这将返回一个IObservable<T>,它可用于监听属性的更改:

var textBlock = new TextBlock();
var text = textBlock.GetObservable(TextBlock.TextProperty);

每个可以被订阅的属性都有一个名为[PropertyName]Property的静态只读字段,该字段被传递给GetObservable以订阅对属性的更改。

IObservable(Reactive Extensions的一部分,或者简称rx)超出了本指南的范围,但这里有一个示例,它使用返回的可观察对象(observable)将带有更改属性值的消息打印到控制台:

var textBlock = new TextBlock();
var text = textBlock.GetObservable(TextBlock.TextProperty);
text.Subscribe(value => Console.WriteLine(value + " Changed"));

当订阅了返回的可观察对象后,它将立即返回属性的当前值,然后在每次属性更改时推送一个新值。如果不需要当前值,可以使用rx Skip运算符:

var text = textBlock.GetObservable(TextBlock.TextProperty).Skip(1);

绑定到可观察对象

您可以使用AvaloniaObject.Bind方法将属性绑定到可观察对象:

// 我们在这里使用Rx Subject,以便我们可以使用OnNext推送新值
var source = new Subject<string>();
var textBlock = new TextBlock();

// 将TextBlock.Text绑定到源
var subscription = textBlock.Bind(TextBlock.TextProperty, source);

// 将textBlock.Text设置为“hello”
source.OnNext("hello");
// 将textBlock.Text设置为“world!”
source.OnNext("world!");

// 终止绑定
subscription.Dispose();

请注意,Bind方法返回可用于终止绑定的IDisposable。如果您从未调用过,那么绑定将在可观察对象通过OnCompleted或OnError完成时自动终止。

在对象初始值设定项中设置绑定

在对象初始化器中设置绑定通常很有用。可以使用索引器执行此操作:

var source = new Subject<string>();
var textBlock = new TextBlock
{
    Foreground = Brushes.Red,
    MaxWidth = 200,
    [!TextBlock.TextProperty] = source.ToBinding(),
};

使用此方法,您还可以轻松地将一个控件上的属性绑定到另一个控件的属性:

var textBlock1 = new TextBlock();
var textBlock2 = new TextBlock
{
    Foreground = Brushes.Red,
    MaxWidth = 200,
    [!TextBlock.TextProperty] = textBlock1[!TextBlock.TextProperty],
};

当然,索引器也可以在对象初始化器的外部使用:

textBlock2[!TextBlock.TextProperty] = textBlock1[!TextBlock.TextProperty];

此语法的唯一缺点是不返回IDisposable。如果需要手动终止绑定,则应使用Bind方法。

转换绑定值

因为我们使用的是可观测对象,所以我们可以很容易地转换绑定的值!

var source = new Subject<string>();
var textBlock = new TextBlock
{
    Foreground = Brushes.Red,
    MaxWidth = 200,
    [!TextBlock.TextProperty] = source.Select(x => "Hello " + x).ToBinding(),
};

使用代码中的XAML绑定

有时,当您需要XAML绑定提供的其他功能时,从代码中使用XAML绑定会更简便。例如,仅使用可观测对象,就可以绑定到DataContext上的属性,如下所示:

var textBlock = new TextBlock();
var viewModelProperty = textBlock.GetObservable(TextBlock.DataContext)
    .OfType<MyViewModel>()
    .Select(x => x?.Name);
textBlock.Bind(TextBlock.TextProperty, viewModelProperty);

但是,在这种情况下,最好使用XAML绑定:

var textBlock = new TextBlock
{
    [!TextBlock.TextProperty] = new Binding("Name")
};

或者,如果需要IDisposable来终止绑定:

var textBlock = new TextBlock();
var subscription = textBlock.Bind(TextBlock.TextProperty, new Binding("Name"));

subscription.Dispose();

订阅任意对象的属性

GetObservable方法返回跟踪单个实例上属性更改的可观察对象。但是,如果正在编写控件,则可能需要实现未绑定到对象实例的OnPropertyChanged方法。

在WPF中,这是通过将静态PropertyChangedCallback传递给DependencyProperty注册方法来完成的,但这只允许控件开发者注册属性更改的回调。

此外,还有一个AddClassHandler扩展方法,它可以自动将事件路由到控件上的方法。

例如,如果您想监听控件的Foo属性的更改,可以这样做:

static MyControl()
{
    FooProperty.Changed.AddClassHandler<MyControl>(x => x.FooChanged);
}

private void FooChanged(AvaloniaPropertyChangedEventArgs e)
{
    // e参数描述了更改的内容。
}

绑定到INotifyPropertyChanged对象

还可以绑定到实现了INotifyPropertyChanged的对象。

var textBlock = new TextBlock();

var binding = new Binding 
{ 
    Source = someObjectImplementingINotifyPropertyChanged, 
    Path = nameof(someObjectImplementingINotifyPropertyChanged.MyProperty)
}; 

textBlock.Bind(TextBlock.TextProperty, binding);
上一页绑定到任务和可观察对象下一页在控件模板中实现绑定

最后更新于2年前

这有帮助吗?

要做到这一点,您可以订阅,这是一个可观察对象,在任何实例上更改属性时都会触发。

🔁
AvaloniaProperty.Changed