From bd8b55ffa5ec18941ec81ffd96a7662da16efdd5 Mon Sep 17 00:00:00 2001 From: Zhang Dian <54255897+zdpcdt@users.noreply.github.com> Date: Fri, 11 Aug 2023 11:10:04 +0800 Subject: [PATCH] docs: data binding. --- .../guides/data-binding/binding-classes.md | 14 ++-- .../guides/data-binding/binding-from-code.md | 72 +++++++++---------- .../data-binding/binding-to-controls.md | 34 ++++----- .../data-binding/how-to-bind-can-execute.md | 18 ++--- .../data-binding/how-to-bind-image-files.md | 33 ++++----- .../guides/data-binding/how-to-bind-tabs.md | 16 ++--- .../how-to-bind-to-a-collection.md | 43 ++++------- ...ow-to-bind-to-a-command-with-reactiveui.md | 46 ++++++------ ...to-bind-to-a-command-without-reactiveui.md | 36 +++++----- .../how-to-bind-to-a-task-result.md | 18 ++--- .../how-to-bind-to-an-observable.md | 12 ++-- ...-create-a-custom-data-binding-converter.md | 28 ++++---- .../data-binding/inotifypropertychanged.md | 42 +++++------ 13 files changed, 189 insertions(+), 223 deletions(-) diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-classes.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-classes.md index 8c21e5fce..962c88f76 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-classes.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-classes.md @@ -1,24 +1,24 @@ --- id: binding-classes -title: How To Bind Style Classes +title: 如何绑定样式类 --- -# How To Bind Style Classes +# 如何绑定样式类 -This guide will show you how to apply style classes to a control depending on the Boolean value of a data binding. +本指南将向您展示如何根据数据绑定的布尔值为控件应用样式类。 -To do this, you will need some classes defined in a `` collection that target the control class you are using. +要做到这一点,您需要在一个 `` 集合中定义一些针对您正在使用的控件类的类。 -You can then conditionally apply the classes to a control using special classes syntax and a data binding. The syntax is like this: +然后,您可以使用特殊的类语法和数据绑定有条件地将类应用于控件。语法如下: ``` ``` -## Example +## 示例 -In this example, two styles with class selectors have been defined. These give a text block either a red or a green background. The style class binding assigns `class1` when the `IsClass1` property of an item is true. Using the negation operator, `class2` is assigned when the `IsClass1` property is false. +在这个示例中,已经定义了两个带有类选择器的样式。这些样式为文本块提供了红色或绿色的背景。当项目的 `IsClass1` 属性为真时,样式类绑定将分配 `class1`。使用否定运算符,当 `IsClass1` 属性为假时,将分配 `class2`。 ```xml title='XAML' diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-from-code.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-from-code.md index 2260fe9a6..497884dc5 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-from-code.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-from-code.md @@ -1,25 +1,25 @@ --- id: binding-from-code -title: How To Bind from Code +title: 如何从代码中绑定 --- -# How To Bind from Code +# 如何从代码中绑定 -Binding from code in Avalonia works somewhat differently to WPF/UWP. At the low level, Avalonia's binding system is based on Reactive Extensions' `IObservable` which is then built upon by XAML bindings (which can also be instantiated in code). +在Avalonia中,从代码中绑定与WPF/UWP中的方式有些不同。在底层,Avalonia的绑定系统基于Reactive Extensions的 `IObservable`,然后由XAML绑定进行构建(这些绑定也可以在代码中实例化)。 -## Subscribing to Changes to a Property +## 订阅属性的更改 -You can subscribe to changes on a property by calling the `GetObservable` method. This returns an `IObservable` which can be used to listen for changes to the property: +您可以通过调用 `GetObservable` 方法来订阅属性的更改。这将返回一个 `IObservable`,可用于监听属性的更改: ```csharp var textBlock = new TextBlock(); var text = textBlock.GetObservable(TextBlock.TextProperty); ``` -Each property that can be subscribed to has a static readonly field called `[PropertyName]Property` which is passed to `GetObservable` in order to subscribe to the property's changes. +每个可订阅的属性都有一个静态只读字段,称为 `[PropertyName]Property`,该字段在 `GetObservable` 中传递以订阅属性的更改。 -`IObservable` (part of Reactive Extensions, or rx for short) is out of scope for this guide, but here's an example which uses the returned observable to print a message with the changing property values to the console: +`IObservable`(是Reactive Extensions的一部分,简称为rx)超出了本指南的范围,但以下是一个示例,该示例使用返回的可观察对象将更改的属性值打印到控制台: ```csharp var textBlock = new TextBlock(); @@ -27,38 +27,38 @@ var text = textBlock.GetObservable(TextBlock.TextProperty); text.Subscribe(value => Console.WriteLine(value + " Changed")); ``` -When the returned observable is subscribed, it will return the current value of the property immediately and then push a new value each time the property changes. If you don't want the current value, you can use the rx `Skip` operator: +当订阅返回的可观察对象时,它将立即返回属性的当前值,然后在每次属性更改时推送一个新值。如果您不想要当前值,可以使用 rx 的 `Skip` 运算符: ```csharp var text = textBlock.GetObservable(TextBlock.TextProperty).Skip(1); ``` -## Binding to an observable +## 绑定到可观察对象 -You can bind a property to an observable using the `AvaloniaObject.Bind` method: +您可以使用 `AvaloniaObject.Bind` 方法将属性绑定到可观察对象: ```csharp -// We use an Rx Subject here so we can push new values using OnNext +// 在这里我们使用Rx Subject,以便我们可以使用OnNext推送新值 var source = new Subject(); var textBlock = new TextBlock(); -// Bind TextBlock.Text to source +// 将TextBlock.Text绑定到source var subscription = textBlock.Bind(TextBlock.TextProperty, source); -// Set textBlock.Text to "hello" +// 将textBlock.Text设置为"hello" source.OnNext("hello"); -// Set textBlock.Text to "world!" +// 将textBlock.Text设置为"world!" source.OnNext("world!"); -// Terminate the binding +// 终止绑定 subscription.Dispose(); ``` -Notice that the `Bind` method returns an `IDisposable` which can be used to terminate the binding. If you never call this, then then binding will automatically terminate when the observable finishes via `OnCompleted` or `OnError`. +请注意,`Bind` 方法返回一个 `IDisposable`,可用于终止绑定。如果您从不调用此方法,那么当可观察对象通过 `OnCompleted` 或 `OnError` 结束时,绑定将自动终止。 -## Setting a binding in an object initializer +## 在对象初始化器中设置绑定 -It is often useful to set up bindings in object initializers. You can do this using the indexer: +在对象初始化器中设置绑定通常很有用。您可以使用索引器来实现此目的: ```csharp var source = new Subject(); @@ -70,7 +70,7 @@ var textBlock = new TextBlock }; ``` -Using this method you can also easily bind a property on one control to a property on another: +使用此方法,您还可以轻松地将一个控件的属性绑定到另一个控件的属性: ```csharp var textBlock1 = new TextBlock(); @@ -82,17 +82,17 @@ var textBlock2 = new TextBlock }; ``` -Of course the indexer can be used outside object initializers too: +当然,索引器也可以在对象初始化器之外使用: ```csharp textBlock2[!TextBlock.TextProperty] = textBlock1[!TextBlock.TextProperty]; ``` -The only downside of this syntax is that no `IDisposable` is returned. If you need to manually terminate the binding then you should use the `Bind` method. +这种语法的唯一缺点是不会返回 `IDisposable`。如果您需要手动终止绑定,则应使用 `Bind` 方法。 -## Transforming binding values +## 转换绑定值 -Because we're working with observables, we can easily transform the values we're binding! +因为我们使用的是可观察对象,所以可以很容易地转换我们绑定的值! ```csharp var source = new Subject(); @@ -104,9 +104,9 @@ var textBlock = new TextBlock }; ``` -## Using XAML bindings from code +## 从代码中使用 XAML 绑定 -Sometimes when you want the additional features that XAML bindings provide, it's easier to use XAML bindings from code. For example, using only observables you could bind to a property on `DataContext` like this: +有时,当您想要使用XAML绑定提供的附加功能时,从代码中使用 XAML 绑定会更加容易。例如,仅使用可观察对象,您可以像这样绑定到 `DataContext` 上的属性: ```csharp var textBlock = new TextBlock(); @@ -116,7 +116,7 @@ var viewModelProperty = textBlock.GetObservable(TextBlock.DataContext) textBlock.Bind(TextBlock.TextProperty, viewModelProperty); ``` -However, it might be preferable to use a XAML binding in this case: +然而,在这种情况下,使用 XAML 绑定可能更可取: ```csharp var textBlock = new TextBlock @@ -125,7 +125,7 @@ var textBlock = new TextBlock }; ``` -Or, if you need an `IDisposable` to terminate the binding: +或者,如果您需要一个 `IDisposable` 来终止绑定: ```csharp var textBlock = new TextBlock(); @@ -134,17 +134,17 @@ var subscription = textBlock.Bind(TextBlock.TextProperty, new Binding("Name")); subscription.Dispose(); ``` -## Subscribing to a Property on Any Object +## 订阅任何对象的属性 -The `GetObservable` method returns an observable that tracks changes to a property on a single instance. However, if you're writing a control you may want to implement an `OnPropertyChanged` method which isn't tied to an instance of an object. +`GetObservable` 方法返回一个可观察对象,用于跟踪单个实例上属性的更改。但是,如果您正在编写一个控件,可能希望实现一个与对象实例无关的 `OnPropertyChanged` 方法。 -To do this you can subscribe to [`AvaloniaProperty.Changed`](http://reference.avaloniaui.net/api/Avalonia/AvaloniaProperty/65237C52) which is an observable which fires _every time the property is changed on any instance_. +要做到这一点,您可以订阅 [`AvaloniaProperty.Changed`](http://reference.avaloniaui.net/api/Avalonia/AvaloniaProperty/65237C52),这是一个可观察对象,_每次在任何实例上更改属性时都会触发该对象_。 -> In WPF this is done by passing a static `PropertyChangedCallback` to the `DependencyProperty` registration method, but this only allows the control author to register a property changed callback. +> 在 WPF 中,通过将静态的 `PropertyChangedCallback` 传递给 `DependencyProperty` 注册方法来完成此操作,但这只允许控件作者注册属性更改回调。 -In addition there is an `AddClassHandler` extension method which can automatically route the event to a method on your control. +此外,还有一个 `AddClassHandler` 扩展方法,可以自动将事件路由到控件上的方法。 -For example if you want to listen to changes to your control's `Foo` property you'd do it like this: +例如,如果您想要监听对控件的 `Foo` 属性的更改,可以像这样做: ```csharp static MyControl() @@ -154,13 +154,13 @@ static MyControl() private void FooChanged(AvaloniaPropertyChangedEventArgs e) { - // The 'e' parameter describes what's changed. + // 'e' 参数描述了发生的更改。 } ``` -## Binding to `INotifyPropertyChanged` objects +## 绑定到实现了 `INotifyPropertyChanged` 的对象 -Binding to objects that implements `INotifyPropertyChanged` is also available. +也可以绑定到实现了 `INotifyPropertyChanged` 的对象。 ```csharp var textBlock = new TextBlock(); diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-to-controls.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-to-controls.md index 4ce85d3da..91eb8cefd 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-to-controls.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/binding-to-controls.md @@ -1,40 +1,40 @@ --- id: binding-to-controls -title: How To Bind to a Control +title: 如何绑定到控件 --- -# How To Bind to a Control +# 如何绑定到控件 -With _Avalonia UI_, as well as binding to a data context you can also bind one control directly to another. +在 _Avalonia UI_ 中,除了绑定到数据上下文(DataContext)外,您还可以直接将一个控件绑定到另一个控件。 :::info -Note that this technique does not use a data context at all. When you do this, you are binding directly to another control itself. +请注意,这种技术完全不使用数据上下文。在执行此操作时,您是直接将一个控件绑定到另一个控件本身。 ::: -## Binding to a Named Control +## 绑定到命名控件 -If you want to bind to a property on another named control, you can use the control name prefixed by a `#` character. +如果要绑定到另一个命名控件上的属性,可以使用以 `#` 字符为前缀的控件名称。 ```markup - + ``` -This is the equivalent to the long-form binding that will be familiar to WPF and UWP users: +这相当于 WPF 和 UWP 开发者熟悉的长格式绑定: ```markup ``` -_Avalonia UI_ supports both syntaxes. +_Avalonia UI_ 支持这两种语法。 -## Binding to an Ancestor +## 绑定到祖先控件 -You can bind to the (logical control tree) parent of the target using the `$parent` syntax: +您可以使用 `$parent` 语法绑定到目标的(逻辑控件树)父级: ```markup @@ -42,7 +42,7 @@ You can bind to the (logical control tree) parent of the target using the `$pare ``` -Or to any level of ancestor by using an index with the `$parent` syntax: +或者使用带有 `$parent` 语法的索引绑定到任何级别的祖先: ```markup @@ -52,9 +52,9 @@ Or to any level of ancestor by using an index with the `$parent` syntax: ``` -The index is zero based so `$parent[0]` is equivalent to `$parent`. +索引从0开始,因此 `$parent[0]` 等同于 `$parent`。 -You can also bind to the closest ancestor of a given type, like this: +您还可以绑定到指定类型的最近祖先,如下所示: ```markup @@ -64,7 +64,7 @@ You can also bind to the closest ancestor of a given type, like this: ``` -Finally, you can combine the index and the type: +最后,您可以结合索引和类型: ```markup @@ -76,7 +76,7 @@ Finally, you can combine the index and the type: ``` -If you need to include a XAML namespace in the ancestor type, you separate the namespace and class using a colon, like this: +如果需要在祖先类型中包含 XAML 命名空间,则使用冒号分隔命名空间和类名,如下所示: ```markup @@ -87,5 +87,5 @@ If you need to include a XAML namespace in the ancestor type, you separate the n ``` :::warning -_Avalonia UI_ also supports WPF/UWP's `RelativeSource` syntax which does something similar, but is _not_ the same. `RelativeSource` works on the _visual_ tree whereas the syntax given here works on the _logical_ tree. +_Avalonia UI_ 还支持 WPF/UWP 的 `RelativeSource` 语法,类似但并不相同。`RelativeSource` 在 _视觉_ 树上起作用,而此处给出的语法在 _逻辑_ 树上起作用。 ::: diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-can-execute.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-can-execute.md index b0833f335..5549be60a 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-can-execute.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-can-execute.md @@ -1,16 +1,16 @@ --- id: how-to-bind-can-execute -title: How to Bind Can Execute +title: 如何绑定 Can Execute --- -# How to Bind Can Execute +# 如何绑定 Can Execute -Whether a control, that can initiate an action in response to user interaction, is in its enabled state, is an important principle of the 'revealed functionality' part of user experience design (UX). User confidence is reinforced by disabling commands that cannot run. For example where a button or menu item cannot run due to the current state of an application, they should be presented as inactive. +控件是否处于启用状态,可以响应用户交互并触发操作,是用户体验设计(UX)中“功能可见性”部分的重要原则。通过禁用无法运行的命令,可以增强用户的信心。例如,如果按钮或菜单项由于应用程序的当前状态而无法运行,则应呈现为不活动状态。 -This example assumes that you are using the MVVM implementation pattern with the _ReactiveUI_ framework. This (recommended) approach gives a very clear separation between the view and the view model. +本示例假设您正在使用带有 _ReactiveUI_ 框架的 MVVM 实现模式。这种(推荐的)方法在视图和视图模型之间提供了非常清晰的分离。 -In this example, the button can only be clicked when the message is not empty. As soon as the output is shown; the message is reset to the empty string - which in turn will disable the button again. +在此示例中,只有在消息不为空时,才能单击按钮。一旦输出显示出来,消息就会重置为空字符串,从而再次禁用按钮。 ```xml title='XAML' @@ -74,16 +74,16 @@ namespace AvaloniaGuides.ViewModels } ``` -In the constructor of the view model, the reactive command is created with two parameters. The first is the private method that performs the action. The second is an observable which is created by the `WhenAnyValue` method of the `ReactiveObject` that underlies the view model (from the `ViewModelBase` class). +在视图模型的构造函数中,使用两个参数创建了响应式命令。第一个参数是执行操作的私有方法。第二个参数是由视图模型(来自 `ViewModelBase` 类)的 `ReactiveObject` 的 `WhenAnyValue` 方法创建的可观察对象。 :::info -The `ViewModelBase` class is added to your project when you use the 'Avalonia MVVM Application' solution template. +在使用 "Avalonia MVVM Application" 解决方案模板时,将会向您的项目中添加 `ViewModelBase` 类。 ::: -Here the `WhenAnyValue` method takes two arguments, the first collects a value for the parameter of the validation function, and the second is the validation function that returns a Boolean result. +在这里,`WhenAnyValue` 方法接受两个参数,第一个参数收集验证函数参数的值,第二个参数是返回布尔结果的验证函数。 :::info -The `WhenAnyValue` method actually has overloads that can take up to 10 different value getters (for the validation function parameters), plus the validation function itself. +实际上,`WhenAnyValue` 方法有多个重载,最多可以接受 10 个不同的值获取器(用于验证函数参数),以及验证函数本身。 ::: diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-image-files.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-image-files.md index eda8b3eff..e4cd8498b 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-image-files.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-image-files.md @@ -1,22 +1,22 @@ --- id: how-to-bind-image-files -title: How To Bind Image Files +title: 如何绑定图像文件 --- -# How To Bind Image Files +# 如何绑定图像文件 :::info -For a complete, runnable example of these concepts in action, check out [the sample application.](https://github.com/AvaloniaUI/AvaloniaUI.QuickGuides/tree/main/LoadingImages) +要在实际操作中查看这些概念的完整可运行示例,请查看[示例应用程序](https://github.com/AvaloniaUI/AvaloniaUI.QuickGuides/tree/main/LoadingImages)。 ::: -In Avalonia UI, binding to an image file opens up opportunities for displaying dynamic image content within your application. This guide provides an overview on how to bind image files from various sources. +在Avalonia UI中,绑定图像文件为在应用程序中显示动态图像内容提供了机会。本指南提供了有关如何从各种来源绑定图像文件的概述。 -## Binding to Image Files from Various Sources +## 从不同来源绑定图像文件 -Assuming you have images from various sources (i.e., a local resource or a web URL) that you want to display in your view, here's how you can achieve this: +假设您有来自不同来源(例如,本地资源或Web URL)的图像,您希望在视图中显示这些图像,下面是如何实现的: -First, in your `ViewModel`, you need to define properties that represent these image sources. The properties can be of type `Bitmap` or `Task` (if loading the image involves an asynchronous operation). The `ImageHelper` class is used to load these images. +首先,在您的 `ViewModel` 中,您需要定义表示这些图像来源的属性。这些属性可以是 `Bitmap` 类型或 `Task` 类型(如果加载图像涉及异步操作)。使用 `ImageHelper` 类来加载这些图像。 ```csharp public class MainWindowViewModel : ViewModelBase @@ -26,7 +26,7 @@ public class MainWindowViewModel : ViewModelBase } ``` -You'll need to have a helper class `ImageHelper` that provides methods to load images from resources and from a web URL. Here's how you can implement this class: +您需要一个名为 `ImageHelper` 的辅助类,该类提供从资源和Web URL加载图像的方法。下面是如何实现这个类: ```csharp using System; @@ -66,9 +66,9 @@ namespace ImageExample.Helpers } ``` -The `LoadFromResource` method takes a resource URI and loads the image using the `AssetLoader` class provided by Avalonia. The `LoadFromWeb` method loads an image from a web URL using the `HttpClient` class. +`LoadFromResource` 方法接受资源URI并使用Avalonia提供的 `AssetLoader` 类加载图像。`LoadFromWeb` 方法使用 `HttpClient` 类从Web URL加载图像。 -Then, in your view, you can bind these image sources to `Image` controls: +然后,在您的视图中,您可以将这些图像来源绑定到 `Image` 控件: ```xml @@ -78,15 +78,6 @@ Then, in your view, you can bind these image sources to `Image` controls: ``` -The `Source` property of the `Image` control can accept various types of image sources including a file path, a URL, or a resource. Please note that for asynchronous image sources, you must use the `^` character after the binding expression to tell Avalonia that this is an asynchronous binding. - -Ensure that local image file paths are accurate, the image file is accessible, and if it's part of your application resources, it's been correctly included in your project. If you're binding to a web image, ensure that the URL is reachable. - - - - - - - - +`Image` 控件的 `Source` 属性可以接受各种类型的图像来源,包括文件路径、URL或资源。请注意,对于异步图像来源,必须在绑定表达式后使用 `^` 字符,以告诉Avalonia这是一个异步绑定。 +请确保本地图像文件路径准确,图像文件可访问,并且如果它是应用程序资源的一部分,则已正确包含在您的项目中。如果要绑定到Web图像,请确保URL可访问。 diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-tabs.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-tabs.md index dbeb05967..c1ff59130 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-tabs.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-tabs.md @@ -1,16 +1,16 @@ --- id: how-to-bind-tabs -title: How To Bind Tabs +title: 如何绑定选项卡 --- -## Binding Support Example +## 绑定支持示例 -You can dynamically create tab items with **data binding**. To do this, bind the `Items` property of a tab control to an array of objects representing the tab header and content. +您可以使用**数据绑定**来动态创建选项卡项。为此,请将选项卡控件的 `Items` 属性绑定到一个代表选项卡标题和内容的对象数组。 -You can then use a **data template** to display the objects. +然后,您可以使用**数据模板(`DataTemplate`)**来显示这些对象。 -This example uses an array of objects created from this `TabItemModel` class: +此示例使用从 `TabItemModel` 类创建的对象数组: ```csharp public class TabItemModel @@ -25,7 +25,7 @@ public class TabItemModel } ``` -Create an array of two `TabItemModel` instances and bind it to the DataContext. +创建一个包含两个 `TabItemModel` 实例的数组,并将其绑定到数据上下文。 ```csharp DataContext = new TabItemModel[] { @@ -34,9 +34,9 @@ DataContext = new TabItemModel[] { }; ``` -The `TabStrip` header content is defined by ItemTemplate property, while `TabItem`'s content is defined by ContentTemplate property. +`TabStrip` 头部内容由 `ItemTemplate` 属性定义,而 `TabItem` 的内容由 `ContentTemplate` 属性定义。 -Finally create a `TabControl` and bind its Items property to the DataContext. +最后,创建一个 `TabControl`,并将其 `Items` 属性绑定到数据上下文(`DataContext`)。 ```markup diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-collection.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-collection.md index aa0357a88..bed0f4942 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-collection.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-collection.md @@ -1,18 +1,18 @@ --- id: how-to-bind-to-a-collection -title: How to Bind to a Collection +title: 如何绑定到集合 --- -# How to Bind to a Collection +# 如何绑定到集合 -Binding to a collection in Avalonia UI is an effective way to display dynamic data. This guide will demonstrate how to bind an `ObservableCollection` to a control, like a `ListBox` or `ItemsControl`, to show a list of items. +在 Avalonia UI 中绑定到集合是一种有效的显示动态数据的方法。本指南将演示如何将 `ObservableCollection` 绑定到控件,比如 `ListBox` 或 `ItemsControl`,以显示一系列项目。 -## Binding to a Simple ObservableCollection +## 绑定到简单的 ObservableCollection -For a start, consider you have an `ObservableCollection` and you want to bind it to a `ListBox` to display a list of string items. +首先,假设您有一个 `ObservableCollection`,您希望将其绑定到一个 `ListBox` 以显示字符串项目的列表。 -Here's an example `ViewModel` with an `ObservableCollection`: +以下是一个带有 `ObservableCollection` 的示例 `ViewModel`: ```csharp public class ViewModel : ObservableObject @@ -32,17 +32,17 @@ public class ViewModel : ObservableObject } ``` -In your view, you can bind this `ObservableCollection` to a `ListBox` like so: +在您的视图中,您可以这样将这个 `ObservableCollection` 绑定到 `ListBox`: ```xml ``` -## Binding to an ObservableCollection of Complex Objects +## 绑定到一个包含复杂对象的 ObservableCollection -But what if your `ObservableCollection` contains complex objects that themselves need to propagate changes? Let's modify our `ViewModel` to accommodate this scenario. +但如果您的 `ObservableCollection` 包含复杂对象,这些对象本身也需要传播更改怎么办?让我们修改我们的 `ViewModel` 来适应这种情况。 -Consider a `Person` class: +考虑一个 `Person` 类: ```csharp public class Person : ObservableObject @@ -64,7 +64,7 @@ public class Person : ObservableObject } ``` -And an `ObservableCollection` in our ViewModel: +以及在我们的 `ViewModel` 中的一个 `ObservableCollection`: ```csharp public class ViewModel : ObservableObject @@ -88,7 +88,7 @@ public class ViewModel : ObservableObject } ``` -You can bind this `ObservableCollection` to a `ListBox` in your view, and use a `DataTemplate` to specify how each `Person` should be presented: +您可以在视图中将这个 `ObservableCollection` 绑定到 `ListBox`,并使用 `DataTemplate` 来指定每个 `Person` 应该如何呈现: ```xml @@ -103,21 +103,4 @@ You can bind this `ObservableCollection` to a `ListBox` in your view, and use a ``` -In this scenario, each `Person` in the list will be displayed with their `Name` and `Age` separated by a small margin. If any of items properties change, the `ListBox` item will automatically update. - - - - - - - - - - - - - - - - - +在这种情况下,列表中的每个 `Person` 将以其 `Name` 和 `Age` 分开的方式显示,并带有一个小间距。如果任何项目的属性发生更改,`ListBox` 项目将自动更新。 diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-command-with-reactiveui.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-command-with-reactiveui.md index 54349a73d..f7e823d4b 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-command-with-reactiveui.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-command-with-reactiveui.md @@ -1,12 +1,12 @@ --- id: how-to-bind-to-a-command-with-reactiveui -title: How to Bind to a Command with ReactiveUI +title: 如何使用ReactiveUI绑定命令 --- -# How to Bind to a Command with ReactiveUI +# 如何使用ReactiveUI绑定命令 -This guide shows you how to bind a view model method (that performs an action) to a control that can initiate an action in response to user interaction (for example, a button). This binding is defined in XAML using the `Command` attribute, for example: +本指南将向您展示如何将视图模型方法(执行操作)绑定到可以响应用户交互而启动操作的控件(例如按钮)。此绑定在XAML中使用`Command`属性进行定义,例如: ```csharp @@ -16,38 +16,38 @@ This guide shows you how to bind a view model method (that performs an action) t ``` -This guide assumes that you are using the MVVM implementation pattern, and you have based your view model on the _ReactiveUI_ framework. +本指南假设您正在使用MVVM实现模式,并且您的视图模型基于 _ReactiveUI_ 框架。 :::info -To review the concept behind the MVVM implementation pattern, see [here](../../concepts/the-mvvm-pattern/). +要了解MVVM实现模式背后的概念,请参阅[此处](../../concepts/the-mvvm-pattern/)。 ::: -If you created your application using the **Avalonia MVVM Application** solution template then your solution will already contain the _ReactiveUI_ framework package, and you can reference it like this: +如果您使用**Avalonia MVVM Application**解决方案模板创建了应用程序,那么您的解决方案已经包含 _ReactiveUI_ 框架包,您可以像这样引用它: ```csharp using ReactiveUI; ``` -A view model that can perform actions implements them through the `ICommand` interface. The _ReactiveUI_ framework provides the `ReactiveCommand` class that implements `ICommand`. +可以通过实现 `ICommand` 接口来执行操作的视图模型通过该接口来实现。_ReactiveUI_ 框架提供了实现 `ICommand` 的 `ReactiveCommand` 类。 :::info -For details of the definition of the `ICommand` interface, see [here](https://docs.microsoft.com/en-gb/dotnet/api/system.windows.input.icommand?view=netstandard-2.0). +有关 `ICommand` 接口定义的详细信息,请参阅[此处](https://docs.microsoft.com/en-gb/dotnet/api/system.windows.input.icommand?view=netstandard-2.0)。 ::: -The `Command` attribute data binding will call the bound view model method through its `ICommand.Execute` interface, when the bound control is activated. In this example: when the button is clicked. +`Command` 属性数据绑定将通过其 `ICommand.Execute` 接口调用绑定的视图模型方法,在绑定的控件被激活时。在这个例子中:当按钮被点击时。 -To create a view model with a `ReactiveCommand`, follow this example: +要创建带有 `ReactiveCommand` 的视图模型,请按照以下示例: -- In your view model, declare a command, like this: +- 在您的视图模型中,声明一个命令,例如: ```csharp public ReactiveCommand ExampleCommand { get; } ``` -- Create a private method in the view model to perform the action. -- Initialize the reactive command, passing the name of the method that performs the action. +- 在视图模型中创建一个私有方法来执行操作。 +- 初始化Reactive命令,传递执行操作的方法的名称。 -Your view model code will now look like this: +您的视图模型代码现在将如下所示: ```csharp namespace AvaloniaGuides.ViewModels @@ -68,15 +68,15 @@ namespace AvaloniaGuides.ViewModels } ``` -- Run the app and monitor the debug output. +- 运行应用程序并监视调试输出。 -When the control bound to the reactive command is activated (in this example: when the button is clicked); then the private method to perform the action is called through the reactive command. +当与Reactive命令绑定的控件被激活时(在本例中:当按钮被点击时),将通过Reactive命令调用执行操作的私有方法。 -## Command Parameter +## 命令参数 -You will often need to pass an argument to the reactive command that is bound to a control. You can achieve this using the `CommandParameter` attribute in the XAML. For example: +通常需要向绑定到控件的Reactive命令传递参数。您可以在XAML中使用 `CommandParameter` 属性来实现这一点。例如: ```markup @@ -88,7 +88,7 @@ You will often need to pass an argument to the reactive command that is bound to ``` -You must now modify the view model so that the reactive commend expects a string parameter, the initialisation expects a string parameter, and the private method to perform the action expects a string parameter. As follows: +现在,您必须修改视图模型,以便Reactive命令期望一个字符串参数,初始化期望一个字符串参数,执行操作的私有方法期望一个字符串参数。如下所示: ```csharp namespace AvaloniaGuides.ViewModels @@ -109,9 +109,9 @@ namespace AvaloniaGuides.ViewModels } ``` -Note that no type conversion is carried out on the `CommandParameter` attribute, so if you need to use a type parameter that is not a string, then you must define the type in the XAML. You will also need to use the expanded XAML syntax for the parameter. +请注意,`CommandParameter` 属性上不会执行任何类型转换,因此,如果您需要使用不是字符串的类型参数,则必须在XAML中定义该类型。您还需要使用扩展的XAML语法来定义参数。 -For example to pass an integer parameter: +例如,要传递整数参数: ```markup @@ -27,7 +27,7 @@ For example, using the XAML as follows: ``` -You can write a view model capable of running the action, like this +你可以编写一个能够运行操作的视图模型,像这样: ```csharp namespace AvaloniaGuides.ViewModels @@ -44,15 +44,15 @@ namespace AvaloniaGuides.ViewModels -## Can Execute? +## 能否执行? -_Avalonia UI_ data binding provides a simple way of implementing a 'can execute?' feature using a naming convention. +_Avalonia UI_ 数据绑定提供了一种使用命名约定来实现“能否执行?”的功能的简单方法。 -If you need to have execution dependent on the value of a command parameter or a view model property, then you can write a second Boolean method to check if the action m,ethod can execute. +如果你需要根据命令参数的值或视图模型属性的值来决定是否执行,那么你可以编写一个第二个布尔方法来检查操作方法是否可以执行。 -To make this work, _Avalonia UI_ uses the naming convention that the Boolean method has the same root name as the action method, but with the added prefix 'Can'. +为了使其工作,_Avalonia UI_ 使用了布尔方法与操作方法相同的根名称,但加上了前缀 `Can` 的命名约定。 -For example: +例如: ```csharp namespace AvaloniaGuides.ViewModels @@ -73,7 +73,7 @@ namespace AvaloniaGuides.ViewModels } ``` -So, extending the example XAML to supply the parameter (string) from a text box: +因此,扩展示例XAML以从文本框提供参数(字符串): ```xml @@ -87,17 +87,17 @@ So, extending the example XAML to supply the parameter (string) from a text box: ``` :::info -This example uses the technique of binding directly to another control. You can see how to do this, [here](binding-to-controls.md). +这个示例使用了直接绑定到另一个控件的技术。你可以在这里看到如何做到这一点,[这里](binding-to-controls.md)。 ::: -You will see that the button becomes enables only when the text box contains a string. +你会发现只有当文本框包含字符串时,按钮才会变为可用状态。 -## **Trigger Can Execute** +## **触发“能否执行”** -If you want to trigger the 'can execute?' method from another property in your view model, then you will have to decorate the property with one or more `DependsOn` attributes, and write the code to invoke property changed events yourself. +如果你想要从视图模型中的另一个属性触发“能否执行”方法,那么你将不得不为该属性添加一个或多个 `DependsOn` 属性,并编写代码来手动调用属性更改事件。 :::info -This technique applies to a view model that is not using the _ReactiveUI_ framework. +这种技术适用于没有使用 _ReactiveUI_ 框架的视图模型。 ::: diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-task-result.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-task-result.md index 39b2657df..9d3628960 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-task-result.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-a-task-result.md @@ -1,35 +1,35 @@ --- id: how-to-bind-to-a-task-result -title: How to Bind to a Task Result +title: 如何绑定任务结果 --- -# How to Bind to a Task Result +# 如何绑定任务结果 -Content in preparation. +内容正在准备中。 -## Example 2: Binding to a task +## 示例2:绑定到任务 -If you need to do some heavy work to load the content of a property you can bind to the result of an `async Task` +如果您需要进行一些繁重的工作来加载属性的内容,您可以绑定到 `async Task` 的结果。 -Consider you have the following view model which generates some text in a long running process: +假设您有以下的视图模型,它在一个长时间运行的过程中生成一些文本: ```csharp public Task MyAsyncText => GetTextAsync(); private async Task GetTextAsync() { - await Task.Delay(1000); // The delay is just for demonstration purpose + await Task.Delay(1000); // 仅为演示目的而进行延迟 return "Hello from async operation"; } ``` -You can bind to the result in the following way: +您可以按照以下方式绑定到结果: ```markup ``` :::info -Note: You can use `FallbackValue` to display some loading indicator. +注意:您可以使用 `FallbackValue` 来显示一些加载指示器。 ::: diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-an-observable.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-an-observable.md index 9f444c4eb..b9a8d6592 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-an-observable.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-bind-to-an-observable.md @@ -1,18 +1,18 @@ --- id: how-to-bind-to-an-observable -title: How To Bind to an Observable +title: 如何绑定到可观察对象 --- -# How To Bind to an Observable +# 如何绑定到可观察对象 -Content in preparation. +内容正在准备中。 -You can subscribe to the result of a task or an observable by using the `^` stream binding operator. +您可以使用 `^` 流绑定操作符订阅任务或可观察对象的结果。 -## Example 1: Binding to an observable +## 示例1:绑定到可观察对象 -For example if `DataContext.Name` is an `IObservable` then the following example will bind to the length of each string produced by the observable as each value is produced +例如,如果 `DataContext.Name` 是一个 `IObservable`,那么以下示例将绑定到可观察对象产生的每个字符串的长度,随着每个值的产生而变化: ```markup diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-create-a-custom-data-binding-converter.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-create-a-custom-data-binding-converter.md index e4648d2b1..dd1fd1c20 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-create-a-custom-data-binding-converter.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/data-binding/how-to-create-a-custom-data-binding-converter.md @@ -1,22 +1,22 @@ --- id: how-to-create-a-custom-data-binding-converter -title: How to Create a Custom Data Binding Converter +title: 如何创建自定义数据绑定转换器 --- -# How to Create a Custom Data Binding Converter +# 如何创建自定义数据绑定转换器 -When one of the built-in data binding converters does not meet your conversion requirements, you can write a custom converter based on the `IValueConverter` interface. This guide will show you how. +当内置的数据绑定转换器不满足您的转换需求时,您可以根据 `IValueConverter` 接口编写自定义转换器。本指南将向您展示如何进行操作。 :::info -To review the _Microsoft_ documentation for the `IValueConverter` interface, see [here](https://docs.microsoft.com/en-gb/dotnet/api/system.windows.data.ivalueconverter?view=netframework-4.7.1). +若要查看 `IValueConverter` 接口的 _Microsoft_ 文档,请点击[此处](https://docs.microsoft.com/en-gb/dotnet/api/system.windows.data.ivalueconverter?view=netframework-4.7.1)。 ::: :::info -As the `IValueConverter` interface was not available in .NET standard 2.0, Avalonia UI contains a copy in the `Avalonia.Data.Converters` namespace. You can see the API documentation about this interface, [here](https://reference.avaloniaui.net/api/Avalonia.Data.Converters/IValueConverter/). +由于在 .NET标准2.0 中无法使用 `IValueConverter` 接口,Avalonia UI 在 `Avalonia.Data.Converters`命名空间中提供了该接口的副本。您可以在这里查看有关此接口的API文档:[这里](https://reference.avaloniaui.net/api/Avalonia.Data.Converters/IValueConverter/)。 ::: -You must reference a custom converter in some resources before it can be used. This can be at any level in your application. In this example, the custom converter `myConverter` is referenced in the window resources: +在使用自定义转换器之前,您必须在某些资源中引用它。这可以在应用程序的任何级别进行。在此示例中,自定义转换器 `myConverter` 被引用在 Window 资源中: ```markup ``` -## Example +## 示例 -This example data binding converter can convert text to specific case from a parameter: +此示例数据绑定转换器可以将文本转换为特定的大小写形式,使用参数进行控制: ```markup ``` -The above XAML assumes that the `textCaseConverter` has been referenced in a resource. +上述XAML假设已在资源中引用了 `textCaseConverter`。 ```csharp public class TextCaseConverter : IValueConverter @@ -83,11 +83,11 @@ public class TextCaseConverter : IValueConverter } ``` -## Target Property Type +## 目标属性类型 -You may want to write a a custom converter that can switch the output type depending on what the target property requires. You can achieve this becuase the `Convert` method receives a `targetType` argument that you can test with the `IsAssignableTo` function. +您可能希望编写一个自定义转换器,根据目标属性的要求切换输出类型。您可以通过 `Convert` 方法接收的 `targetType` 参数进行测试,使用 `IsAssignableTo` 函数来实现这一点。 -In this example, the `animalConverter` can find an image, or a text name for a bound `Animal` class object: +在这个示例中,`animalConverter` 可以为绑定的 `Animal` 类对象查找图像或文本名称: ```xml title='XAML'