From 7c008dc12565e964095ca8a3a3a02d22bca603b1 Mon Sep 17 00:00:00 2001 From: chyuang <837312208@qq.com> Date: Tue, 30 Apr 2024 15:57:21 +0800 Subject: [PATCH] translate event aggregator, dependency injection etc. --- docs/README.md | 13 ++- docs/_sidebar.md | 19 +++- docs/commands/composite-commands.md | 5 +- docs/dependency-injection/index.md | 35 +++--- .../dependency-injection/registering-types.md | 53 ++++----- docs/dialogs/index.md | 25 ++-- docs/event-aggregator.md | 107 +++++++++--------- docs/index.html | 9 +- docs/{introduction.md => index.md} | 4 +- docs/mvvm/bindablebase.md | 2 +- docs/mvvm/viewmodel-locator.md | 60 +++++----- docs/navigation/navigation-parameters.md | 24 ++-- docs/navigation/page-navigation.md | 2 +- .../regions/basic-region-navigation.md | 3 - .../regions/confirming-navigation.md | 3 - .../regions/controlling-view-lifetime.md | 3 - docs/navigation/regions/index.md | 21 ++-- .../regions/navigation-existing-views.md | 3 - docs/navigation/regions/navigation-journal.md | 3 - docs/navigation/regions/passing-parameters.md | 3 - docs/navigation/regions/region-adapters.md | 4 - docs/navigation/regions/region-behaviors.md | 4 - docs/navigation/regions/region-manager.md | 4 - .../regions/view-viewmodel-participation.md | 3 - docs/platforms/wpf/getting-started.md | 4 - .../wpf/interactivity/event-to-command.md | 4 - 26 files changed, 195 insertions(+), 225 deletions(-) rename docs/{introduction.md => index.md} (80%) diff --git a/docs/README.md b/docs/README.md index 80da106..94c4024 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,13 @@ # Prism 中文文档 -> [Prism 官方文档](https://docs.prismlibrary.com/docs/)的中文版本。 +## Prism 概述 +Prism 是一个用于构建松耦合、可维护且可测试的 XAML 应用程序的框架,适用于 WPF、.NET MAUI、Uno平台和 Xamarin Forms。 -# 概述 -点击[Prism简介](introduction.md)开始阅读。 +## 项目简介 +> [Prism 官方文档](https://docs.prismlibrary.com/docs/) 的中文版本。 + +## 在线阅读地址 +https://corey212.github.io/Prism-Documentation-zh/ + +# 快速开始 +点击 [Prism简介](index.md) 开始阅读。 diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 8b42da2..7a7352d 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,5 +1,5 @@ - 目录 - - [Prism简介](introduction.md) + - [Prism简介](index.md) - 命令(Commands) - [命令操作](commands/commanding.md) - [复合命令](commands/composite-commands.md) @@ -8,7 +8,7 @@ - 依赖注入(Dependency Injection) - [开始使用](dependency-injection/index.md) - [注册类](dependency-injection/registering-types.md) - - [微软扩展(补充)](dependency-injection/servicecollection-supplement.md) + - [Microsoft 扩展(补充)](dependency-injection/servicecollection-supplement.md) - [平台特定服务](dependency-injection/platform-specific-services.md) - [异常处理](dependency-injection/resolution-errors.md) - [容器定位器(ContainerLocator)](dependency-injection/container-locator.md) @@ -30,8 +30,23 @@ - [页面导航](navigation/page-navigation.md) - 区域(Regions) - [开始使用](navigation/regions/index.md) + - [区域 Manager](navigation/regions/region-manager.md) + - [区域 Adapters](navigation/regions/region-adapters.md) + - [区域 Behaviors](navigation/regions/region-behaviors.md) + - [关于 Prism 中的导航](navigation/regions/index.md) + - [基础区域导航](navigation/regions/basic-region-navigation.md) + - [View/ViewModel 参与导航](navigation/regions/view-viewmodel-participation.md) + - [导航到现有视图](navigation/regions/navigation-existing-views.md) + - [传递参数](navigation/regions/passing-parameters.md) + - [确认导航](navigation/regions/confirming-navigation.md) + - [控制视图生命周期](navigation/regions/controlling-view-lifetime.md) + - [导航 Journal](navigation/regions/navigation-journal.md) - 平台(Platforms) - Wpf - [介绍](platforms/wpf/introduction.md) + - [开始使用](platforms/wpf/getting-started.md) + - [视图组成](platforms/wpf/view-composition.md) + - 交互 + - [将事件绑定到命令](platforms/wpf/interactivity/event-to-command.md) - 插件(Plugins) - 基本会话 diff --git a/docs/commands/composite-commands.md b/docs/commands/composite-commands.md index 8104b97..792b83d 100644 --- a/docs/commands/composite-commands.md +++ b/docs/commands/composite-commands.md @@ -12,10 +12,9 @@ The `CompositeCommand` class represents a command that is composed from multiple The `CompositeCommand` class maintains a list of child commands (`DelegateCommand` instances). The `Execute` method of the `CompositeCommand` class simply calls the `Execute` method on each of the child commands in turn. The `CanExecute` method similarly calls the `CanExecute` method of each child command, but if any of the child commands cannot be executed, the `CanExecute` method will return `false`. In other words, by default, a `CompositeCommand` can only be executed when all the child commands can be executed. -> [!NOTE] -> `CompositeCommand` can be found in the Prism.Commands namespace which is located in the Prism.Core NuGet package. +?> `CompositeCommand` can be found in the Prism.Commands namespace which is located in the Prism.Core NuGet package. - ## Creating a Composite Command diff --git a/docs/dependency-injection/index.md b/docs/dependency-injection/index.md index dbb4606..176f9bb 100644 --- a/docs/dependency-injection/index.md +++ b/docs/dependency-injection/index.md @@ -1,37 +1,36 @@ -# Dependency Injection with Prism +# 使用 Prism 进行依赖注入 -Prism has always been built around Dependency Injection. This helps you to architect apps that are maintainable and testable and help you reduce or eliminate your dependence on Static and circular references. Prior to Prism 7, dependency injection with Prism was focused around various containers that were implemented for use with Prism. This led to a number of issues including that while docs may have been written showing you how to do something with one container they did not necessarily reflect the appropriate API to use for the container that you were using for your application. +Prism 始终围绕依赖注入构建。这有助于构建可维护和可测试的应用,并帮助您减少或消除对静态和循环引用的依赖。在 Prism 7 之前,Prism 的依赖注入主要集中在与 Prism 一起使用的各种容器上。这导致了许多问题,包括虽然可能已经编写了文档,向您展示了如何使用一个容器执行某些操作,但它们不一定反映用于您用于应用程序的容器的适当 API。 -Prism 7 introduced several new interfaces for abstracting what Prism requires for dependency injection. This has several benefits as you might imagine including: +Prism 7 引入了几个新的接口,用于抽象 Prism 对依赖注入所需的内容。正如您可能想象的那样,这有几个好处,包括: -- Docs showing how to do something in Prism will always show you what you need to do without any concern for which dependency injection container you are using. -- This greatly simplified what needed to be added to any container specific package. In the case of Prism.Forms this reduces each container specific project 3 classes: `PrismApplication`, an implementation of `IContainerExtension` and an extension class to retrieve the underlying container should you feel the need to access it for one of it's API's that is not implemented by Prism. +- 展示如何在 Prism 中执行某些操作的文档将始终向您显示您需要执行的操作,而无需担心您正在使用的依赖项注入容器。 +- 这大大简化了需要添加到任何容器特定包的内容。在 Prism.Forms 的情况下,这将每个特定于容器的项目减少 3 个类: `PrismApplication` 、一个实现 `IContainerExtension` 和一个扩展类,用于检索底层容器,如果您觉得需要访问它,以获得 Prism 未实现的 API 之一。 -In Prism 9, the Prism Ioc layer has been removed from the Prism.Core and now ships independently from Prism. This makes it easier for us to share the container implementation across all supported Prism platforms (WPF, Uno Platform, .NET MAUI, etc). Additional work has been done in Prism 9 to also give the containers better integration with Microsoft.Extensions.DependencyInjection and provide better support for Container Scoping scenarios some of which are used extensively by Prism.Maui. +在 Prism 9 中,Prism Ioc 层已从 Prism.Core 中删除,现在独立于 Prism 发货。这使我们可以更轻松地在所有受支持的 Prism 平台(WPF、Uno 平台、.NET MAUI 等)之间共享容器实现。在 Prism 9 中还完成了其他工作,以便容器更好地与 Microsoft.Extensions.DependencyInjection 集成,并为容器范围方案提供更好的支持,其中一些方案被 Prism.Maui 广泛使用。 -## Using Microsoft's IServiceCollection +## 使用 Microsoft 的 IServiceCollection -Prism 9.0 has separated the Container implementations from the main Prism repo. This allows us to ship and to share the containers across all platforms without any specific code coupling to the Prism.Core. In the updated Prism 9.0 implementations support has been added for Microsoft's IServiceCollection. This helps Prism better support .NET MAUI applications and the IHostBuilder approach used by the Uno.Extensions. It is important to consider that when using Registration Extensions from various Microsoft libraries, these will have been tailored to use for Web Applications. For example if using EntityFrameworkCore the default Lifetime of the DbContext will be set to Scoped. For most Prism applications you will likely want to set this to be Transient as a Singleton could cause DbAccess issues if different ViewModels or Services are accessing the database at the same time. Be sure to spend some time evaluating any prebuilt extension methods for registering services so that you can be sure that the service will have an appropriate lifetime for your application. +Prism 9.0 已将容器实现与主 Prism 存储库分开。这使我们能够在所有平台上交付和共享容器,而无需与 Prism.Core 进行任何特定的代码耦合。在更新的 Prism 9.0 实现中,添加了对 Microsoft 的 IServiceCollection 的支持。这有助于 Prism 更好地支持 .NET MAUI 应用程序和 Uno.Extensions 使用的 IHostBuilder 方法。请务必考虑,在使用各种 Microsoft 库中的注册扩展时,这些扩展将针对 Web 应用程序进行定制。例如,如果使用 EntityFrameworkCore,则 DbContext 的默认生存期将设置为 Scoped。对于大多数 Prism 应用程序,您可能希望将其设置为瞬态,因为如果不同的 ViewModel 或服务同时访问数据库,则 Singleton 可能会导致 DbAccess 问题。请务必花一些时间评估用于注册服务的任何预生成扩展方法,以便确保服务具有适合应用程序的生存期。 -## Containers +## 容器 -The Prism team ships several DI container implementations for the Prism IoC abstractions. +Prism 团队为 Prism IoC 抽象提供了多个 DI 容器实现。 -| Container | Availability | Notes | +| 容器 | 获取 | 说明 | |:---------:|:------------:|:-----:| | DryIoc | NuGet.org | Supported across all targets | | Grace | Commercial Plus | | | Microsoft | Commercial Plus | | | Unity | NuGet.org | Legacy support for Xamarin.Forms and WPF only | -> [!NOTE] -> While the DryIoc and Unity Container's are available on NuGet.org they are still subject to the Prism License. You should have a valid license for Prism. +?> 虽然 DryIoc 和 Unity 容器在 NuGet.org 上可用,但它们仍受 Prism 许可证的约束。您应该拥有 Prism 的有效许可证。 ## Next Steps -- Learn how to [Register Services](xref:DependencyInjection.RegisterServices) -- Learn how to [Register Pages for Navigation](xref:Platforms.XamarinForms.Navigation.Basics) ***(Xamarin Specific)*** -- Learn how to [Register Platform Specific Services](xref:DependencyInjection.IPlatformInitializer) ***(Xamarin Specific - Legacy)*** -- [Microsoft.Extensions.DependencyInjection (Supplement)](xref:DependencyInjection.Supplement) +- 了解如何 [注册服务](xref:DependencyInjection.RegisterServices) +- 了解如何 [注册用于导航的页面(特定于 Xamarin)](xref:Platforms.XamarinForms.Navigation.Basics) ***(Xamarin Specific)*** +- 了解如何 [注册特定于平台的服务(Xamarin 特定 - 旧版)](xref:DependencyInjection.IPlatformInitializer) ***(Xamarin Specific - Legacy)*** +- [Microsoft.Extensions.DependencyInjection(补充)](xref:DependencyInjection.Supplement) -- Learn more about the Prism Container Extensions and working with Shiny in the [Appendix](xref:DependencyInjection.Appendix) +- 在[附录](xref:DependencyInjection.Appendix)中了解有关 Prism 容器扩展和使用 Shiny 的更多信息 diff --git a/docs/dependency-injection/registering-types.md b/docs/dependency-injection/registering-types.md index ce7ece7..3111aef 100644 --- a/docs/dependency-injection/registering-types.md +++ b/docs/dependency-injection/registering-types.md @@ -1,21 +1,20 @@ -# Registering Types with Prism +# 使用 Prism 注册类型 -Similar to most Dependency Injection models, Prism provides abstractions around 3 service lifetimes: +与大多数依赖注入模型类似,Prism 提供了大约 3 个服务生命周期的抽象: -1) Transient (Get a new instance every time the service or type is requested) -2) Singleton (Get the same instance every time the service or type is requested) -3) Scoped (Get a new instance on each container scope, but the same instance within a specific container scope) +1) Transient(瞬态:每次请求服务或类型时获取新实例) +2) Singleton(单例:每次请求服务或类型时获取相同的实例) +3) Scoped(作用域:在每个容器作用域上获取一个新实例,但在特定容器作用域内获取相同的实例) -> [!NOTE] -> By default Prism does not use scoping except within Prism.Maui which creates a scope around each Page. This is used for services such as the `INavigationService`, `IPageDialogService`, and `IDialogService`. +?> 默认情况下,Prism 不使用scoping,除非在 Prism.Maui 中,它会在每个页面周围创建一个scope。 这用于 `INavigationService`、`IPageDialogService` 和 `IDialogService` 等服务. -For those who may be familiar with ASP.NET Core you may be familiar with 3 basic types of dependency registrations: Transients, Singletons, and Scoped Services. Unlike the web environment in which many of your services are scoped around the User Request, for Desktop and Mobile applications we are dealing with a single user. As a result, we must instead decide whether for memory management and other business requirements our services are best suited as a single instance that will be reused throughout our application or whether we will create a new instance each time it is requested and then allow the Garbage Collector to free up the memory when we are done with it. +对于熟悉 ASP.NET Core 的用户可能也会熟悉这 3 种基本类型的依赖项注册:Transients, Singletons和 Scoped 服务。与许多服务都围绕用户请求的 Web 环境不同,对于桌面和移动应用程序,我们处理的是单个用户。因此,我们必须决定,对于内存管理和其他业务需求,我们的服务是否最适合作为将在整个应用程序中重用的单个实例,或者我们是否在每次请求时创建一个新实例,然后允许垃圾回收器在我们完成它时释放内存。 -It is also important to consider that Prism has a hard requirement on the use of named service registrations. This is what allows Prism to register your Page for navigation and then resolve it later based on the Uri segment like `MyMasterDetailPage/NavigationPage/ViewA`. Any Dependency Injection container which does not support named services out of the box therefore cannot and will not be implemented officially by the Prism team. +同样重要的是要考虑到 Prism 对使用指定服务注册有硬性要求。这就是 Prism 允许注册您的页面以进行导航,然后稍后根据 Uri 段(如 `MyMasterDetailPage/NavigationPage/ViewA` .因此,任何不支持开箱即用命名服务的依赖注入容器都不能也不会由 Prism 团队正式实现。 -## Registering Transient Services +## 注册 Transient 服务 -For those services that you expect to create a new instance each time it is created you will simply call the `Register` method and provide the Service Type and the Implementing Type, except in cases where it may be appropriate to simply register the concrete type. +对于那些您期望每次创建时都创建一个新实例的服务,只需调用 Register 方法并提供服务类型和实现类型,除非在某些情况下,简单地注册具体类型可能更为合适。 ```cs // Where it will be appropriate to use FooService as a concrete type @@ -24,12 +23,11 @@ containerRegistry.Register(); containerRegistry.Register(); ``` -## Registering Singleton Services +## 注册 Singleton 服务 -Many times you may have a service which is used throughout your application. As a result it would not be a good idea to create a new instance every time you need the service. In order to provide better memory management it is therefore a better practice to make such services a Singleton that can be used throughout the application. There are also many times in which you may need a service that retains it state throughout the lifecycle of your application. For either of these cases it makes far more sense to register your service as a Singleton. +很多时候,您可能需要一个服务在整个应用程序中使用,因此每次需要该服务时都创建新实例都不是一个好主意。因此,为了提供更好的内存管理,更好的做法是将此类服务设置为可以在整个应用程序中使用的单一实例。在许多情况下,您可能需要在应用程序的整个生命周期中保持其状态的服务。对于这两种情况中的任何一种,将服务注册为单一实例都更有意义。 -> [!NOTE] -> Singleton Services are not actually created, and therefore do not start using memory until the first time the service is resolved by your application. +?> 单例服务实际上并未创建,因此在应用程序首次解析服务之前不会开始使用内存。 ```cs // Where it will be appropriate to use FooService as a concrete type @@ -38,9 +36,9 @@ containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); ``` -### Registering a Service Instance +### 注册服务实例 -While many times you'll want to register a Singleton by simply providing the Service and Implementation types, there are times in which you may want to new up a service instance and provide it for a given service, or in which you may want to register the Current instance from a plugin such as MonkeyCache as shown below: +虽然很多时候您希望通过简单地提供 Service 和 Implementation 类型来注册 Singleton,但有时您可能希望新建服务实例并为给定服务提供它,或者您可能希望从插件(如 MonkeyCache)注册当前实例,如下所示: ```cs containerRegistry.RegisterInstance(new FooImplementation()); @@ -50,12 +48,11 @@ Barrel.ApplicationId = "your_unique_name_here"; containerRegistry.RegisterInstance(Barrel.Current); ``` -## Checking if a Service has been Registered +## 检查服务是否已注册 -There are many times particularly when writing Prism Modules or Plugins in which you may want to check if a service has been registered and then do something based on whether it has or has not been registered. +很多时候,特别是在编写 Prism 模块或插件时,您可能希望检查服务是否已注册,然后根据它是否已注册执行某些操作。 -> [!NOTE] -> When working with Prism Modules if you have a hard dependency on a given service it should be injected into the constructor so as to generate an exception when initializing the Module if the service type is missing. You should only use `IsRegistered` to check for it if your intent is to register a default implementation. +?> 使用 Prism 模块时,如果对给定服务有硬依赖性,则应将其注入构造函数中,以便在初始化模块时在缺少服务类型时生成异常。仅当您的意图是注册默认实现时,才应用于 `IsRegistered` 检查它。 ```cs if (containerRegistry.IsRegistered()) @@ -64,9 +61,9 @@ if (containerRegistry.IsRegistered()) } ``` -## Lazy Resolution +## 延迟加载 -As shown previously you can register your services like `containerRegistry.Register()`. Many developers may have use cases where they want to conserve memory and lazy load services either as `Func` or `Lazy`. Prism 8 supports this out of the box. In order to do this you simply need to add the parameter to your ViewModel or Service as shown below. +如前所述,您可以注册您的服务,例如 `containerRegistry.Register()` 。许多开发人员可能有这样的用例:他们希望节省内存和延迟加载服务, `Func` 或者是 `Lazy` 或 。Prism 8 开箱即用地支持此功能。为此,您只需将参数添加到 ViewModel 或 Service 中,如下所示。 ```cs public class ViewAViewModel @@ -77,12 +74,11 @@ public class ViewAViewModel } ``` -> [!NOTE] -> Take note of the service registration type. It generally does NOT make sense to use `Lazy` or `Func` resolutions when you are working with a Singleton Service. For instance the `IEventAggregator` is a singleton. This means that you get a single instance of the Event Aggregator that is used through the entire application. By using `Lazy` or `Func` you ultimately use more memory and may take performance hits instead of just requesting the service outright. +?> 记下服务注册类型。当您使用单例服务时,使用 `Lazy` 或 `Func` 解决方法通常没有意义。例如,是 `IEventAggregator` 单例。这意味着你将获得整个应用程序中使用的事件聚合器的单个实例。通过使用 `Lazy` 或 `Func` 最终使用更多内存,可能会对性能造成影响,而不仅仅是直接请求服务。 -## Resolve All +## 全部解析 -Some Developers may find the need to Register multiple implementations of the same service contract with an expectation of resolving all of them. As a common use case, Shiny uses this pattern with some of its delegate interfaces. This can allow you to build more modular code by responding to the same event in bite sized chunks. Again there is nothing special that you need to do with the registration. To use this feature you simply need to inject `IEnumerable` into your constructor as show here. +一些开发人员可能需要为同一服务契约注册多个实现,并希望解析所有这些实现。作为一个常见的用例,Shiny使用这种模式处理其一些委托接口。这可以让您通过以小块的方式响应相同的事件来构建更模块化的代码。再次强调,在注册时您不需要做任何特别的事情。要使用这个功能,您只需要在构造函数中注入 `IEnumerable`,正如这里所示。 ```cs public class SomeService @@ -93,5 +89,4 @@ public class SomeService } ``` -> [!NOTE] -> This feature is only supported in DryIoc at this time. This may become available to those using Unity Container once version 6 releases. +?> 此功能目前仅在 DryIoc 中受支持。Prism 6 发布后,使用 Unity 容器的用户可能会使用此功能。 diff --git a/docs/dialogs/index.md b/docs/dialogs/index.md index f695ce4..c75644d 100644 --- a/docs/dialogs/index.md +++ b/docs/dialogs/index.md @@ -1,12 +1,12 @@ -# Getting Started +# 开始 -There are a variety of reasons you may want to create a Dialog in your application. This could be to display a message to your user, or present them with a form to enter some information, etc. Within the Prism.Core we have defined a central abstraction layer for presenting Dialogs across all Prism supported platforms. Dialogs within Prism use the native mechanisms for presenting your custom Views. This enables you to create Dialogs that have the same look and feel as the rest of your application while continuing to use the MVVM pattern. +您可能希望在应用程序中创建对话框的原因有很多。这可能是向用户显示消息,或向他们提供输入某些信息的表单等。在 Prism.Core 中,我们定义了一个中央抽象层,用于在所有 Prism 支持的平台上呈现对话。Prism 中的对话框使用本机机制来显示您的自定义视图。这使您能够创建与应用程序其余部分具有相同外观的对话框,同时继续使用 MVVM 模式。 -## Changes +## 变化 -Prism 9.0 introduces some changes to the `IDialogService` with a goal of helping meet you with the callback code that meets your needs. At the heart of the changes is the introduction of the DialogCallback. The DialogCallback is designed to provide you more flexibility in responding to the `IDialogResult`. This allows you to provide an asynchronous or synchronous delegate. Finally rather than being explicitly prescriptive about what you might need to provide as an argument for your callback, it aims to better meet you. +Prism 9.0 引入了一些更改, `IDialogService` 目的是帮助您使用满足您需求的回调代码。更改的核心是引入 DialogCallback。DialogCallback 旨在让您更灵活地响应 `IDialogResult` .这允许您提供异步或同步委托。最后,它不是明确规定您可能需要提供什么作为回调的论据,而是旨在更好地满足您的需求。 -### On Close +### 关闭 ```cs // Basic Callback @@ -16,7 +16,7 @@ new DialogCallback().OnClose(() => Console.WriteLine("The Dialog Closed")); new DialogCallback().OnClose(result => Console.WriteLine($"The Dialog Button Result is: {result.Result}")); ``` -In addition to the synchronous callbacks shown above each of these has an equivalent for handling asynchronous callbacks: +除了上面显示的同步回调之外,每个回调都有一个处理异步回调的等效项: ```cs // Basic Callback @@ -26,9 +26,9 @@ new DialogCallback().OnCloseAsync(() => Task.CompletedTask); new DialogCallback().OnCloseAsync(result => Task.CompletedTask); ``` -### Error Handling +### 错误处理 -Additionally it will let you provide an error handler which will only be invoked in the case that an Exception is encountered. +此外,它还允许您提供一个错误处理程序,该处理程序仅在遇到异常时才会调用。 ```cs // Basic Error Callback @@ -52,10 +52,9 @@ new DialogCallback().OnError((nre, result) => }); ``` -> [!NOTE] -> Each of the `OnError` samples above also has an equivalent `OnErrorAsync` which accepts a delegate returning a Task as well. +?> 上面的每个 `OnError` 示例也有一个等效项,该等效 `OnErrorAsync` 项也接受返回任务的委托。 -## Next Steps +## 后续步骤 -- [IDialogAware ViewModels](xref:Dialogs.IDialogAware) -- [IDialogWindow](xref:Dialogs.DialogWindow) (WPF & Uno Platform Only) +- [IDialogAware 视图模型](xref:Dialogs.IDialogAware) +- [IDialogWindow](xref:Dialogs.DialogWindow) (仅限 WPF & Uno 平台) diff --git a/docs/event-aggregator.md b/docs/event-aggregator.md index 35ff8b1..4bcd0d5 100644 --- a/docs/event-aggregator.md +++ b/docs/event-aggregator.md @@ -1,18 +1,18 @@ -# Event Aggregator +# 事件聚合器 -The Prism Library provides an event mechanism that enables communications between loosely coupled components in the application. This mechanism, based on the event aggregator service, allows publishers and subscribers to communicate through events and still do not have a direct reference to each other. +Prism Library 提供了一种事件机制,用于实现应用程序中松散耦合组件之间的通信。此机制基于事件聚合器服务,允许发布者和订阅者通过事件进行通信,并且仍然没有直接相互引用。 -The `EventAggregator` provides multicast publish/subscribe functionality. This means there can be multiple publishers that raise the same event and there can be multiple subscribers listening to the same event. Consider using the `EventAggregator` to publish an event across modules and when sending a message between business logic code, such as controllers and presenters. +提供 `EventAggregator` 组播发布/订阅功能。这意味着可以有多个发布者引发同一事件,并且可以有多个订阅者收听同一事件。请考虑使用 `EventAggregator` 跨模块发布事件,以及在业务逻辑代码(如控制器和演示者)之间发送消息时。 -Events created with the Prism Library are typed events. This means you can take advantage of compile-time type checking to detect errors before you run the application. In the Prism Library, the `EventAggregator` allows subscribers or publishers to locate a specific `EventBase`. The event aggregator also allows for multiple publishers and multiple subscribers, as shown in the following illustration. +使用 Prism 库创建的事件是类型化事件。这意味着,在运行应用程序之前,您可以利用编译时类型检查来检测错误。在 Prism 库中,订阅 `EventAggregator` 者或发布者可以查找特定的 `EventBase` .事件聚合器还允许多个发布者和多个订阅者,如下图所示。 ![Using the event aggregator](images/event-aggregator-1.png) -> [!Video https://www.youtube.com/embed/xTP9_hN_3xA] + ## IEventAggregator -The `EventAggregator` class is offered as a service in the container and can be retrieved through the `IEventAggregator` interface. The event aggregator is responsible for locating or building events and for keeping a collection of the events in the system. +该 `EventAggregator` 类在容器中作为服务提供,可以通过 `IEventAggregator` 接口检索。事件聚合器负责查找或构建事件,并负责在系统中保留事件的集合。 ```cs public interface IEventAggregator @@ -21,33 +21,31 @@ public interface IEventAggregator } ``` -The `EventAggregator` constructs the event on its first access if it has not already been constructed. This relieves the publisher or subscriber from needing to determine whether the event is available. +如果事件尚未构造,则在首次访问时 `EventAggregator` 构造事件。这样一来,发布者或订阅者就无需确定事件是否可用。 ## PubSubEvent -The real work of connecting publishers and subscribers is done by the `PubSubEvent` class. This is the only implementation of the `EventBase` class that is included in the Prism Library. This class maintains the list of subscribers and handles event dispatching to the subscribers. +连接发布者和订阅者的实际工作是由 `PubSubEvent` 类完成的。这是 Prism Library 中包含的 `EventBase` 类的唯一实现。此类维护订阅服务器列表并处理向订阅服务器发送的事件。 -The `PubSubEvent` class is a generic class that requires the payload type to be defined as the generic type. This helps enforce, at compile time, that publishers and subscribers provide the correct methods for successful event connection. The following code shows a partial definition of the PubSubEvent class. +该 `PubSubEvent` 类是一个泛型类,它要求将有效负载类型定义为泛型类型。这有助于在编译时强制发布者和订阅者提供正确的方法来成功连接事件。下面的代码演示 PubSubEvent 类的部分定义。 -> [!Note] -> `PubSubEvent` can be found in the Prism.Events namespace which is located in the Prism.Core NuGet package. +?> `PubSubEvent` 可以在 Prism.Core NuGet 包中的 Prism.Events 命名空间中找到。 -## Creating an Event +## 创建 Event -The `PubSubEvent` is intended to be the base class for an application's or module's specific events. `TPayLoad` is the type of the event's payload. The payload is the argument that will be passed to subscribers when the event is published. +旨在 `PubSubEvent` 成为应用程序或模块的特定事件的基类。 `TPayLoad`是事件有效负载的类型。有效负载是在发布事件时将传递给订阅者的参数。 -For example, the following code shows the `TickerSymbolSelectedEvent`. The payload is a string containing the company symbol. Notice how the implementation for this class is empty. +例如,以下代码显示 `TickerSymbolSelectedEvent` .有效负载是包含公司符号的字符串。请注意,此类的实现是空的。 ```cs public class TickerSymbolSelectedEvent : PubSubEvent{} ``` -> [!Note] -> In a composite application, the events are frequently shared between multiple modules, so they are defined in a common place. It is common practice to define these events in a shared assembly such as a "Core" or "Infrastructure" project. +?> 在复合应用程序中,事件经常在多个模块之间共享,因此它们在公共位置进行定义。通常的做法是在共享程序集(如“Core”或“Infrastructure”项目)中定义这些事件。 -## Publishing an Event +## 发布 Event -Publishers raise an event by retrieving the event from the `EventAggregator` and calling the `Publish` method. To access the `EventAggregator`, you can use dependency injection by adding a parameter of type `IEventAggregator` to the class constructor. +发布者通过从 中检索事件 `EventAggregator` 并调用 `Publish` 该方法引发事件。要访问 `EventAggregator` ,可以通过向类构造函数添加类型 `IEventAggregator` 参数来使用依赖注入。 ```cs public class MainPageViewModel @@ -60,15 +58,15 @@ public class MainPageViewModel } ``` -The following code demonstrates publishing the TickerSymbolSelectedEvent. +下面的代码演示如何发布 TickerSymbolSelectedEvent。 ```cs _eventAggregator.GetEvent().Publish("STOCK0"); ``` -## Subscribing to Events +## 订阅 Events -Subscribers can enlist with an event using one of the `Subscribe` method overloads available on the `PubSubEvent` class. +订阅者可以使用 `PubSubEvent` 类上可用的 `Subscribe` 方法重载之一来登记事件。 ```cs public class MainPageViewModel @@ -85,22 +83,22 @@ public class MainPageViewModel } ``` -There are several ways to subscribe to `PubSubEvents`. Use the following criteria to help determine which option best suits your needs: +有几种方法可以订阅 `PubSubEvents` .使用以下条件来帮助确定哪个选项最适合您的需求: -- If you need to be able to update UI elements when an event is received, subscribe to receive the event on the UI thread. -- If you need to filter an event, provide a filter delegate when subscribing. -- If you have performance concerns with events, consider using strongly referenced delegates when subscribing and then manually unsubscribe from the PubSubEvent. -- If none of the preceding is applicable, use a default subscription. +- 如果需要能够在收到事件时更新 UI 元素,请订阅以在 UI 线程上接收事件。 +- 如果需要筛选事件,请在订阅时提供筛选器委托。 +- 如果对事件有性能问题,请考虑在订阅时使用强引用的委托,然后手动取消订阅 PubSubEvent。 +- 如果上述情况均不适用,请使用默认订阅。 -The following sections describe these options. +以下各节介绍这些选项。 -### Subscribing on the UI Thread +### 在 UI 线程上订阅 -Frequently, subscribers will need to update UI elements in response to events. In WPF, only a UI thread can update UI elements. +通常,订阅者需要更新 UI 元素以响应事件。在 WPF 中,只有 UI 线程可以更新 UI 元素。 -By default, the subscriber receives the event on the publisher's thread. If the publisher sends the event from the UI thread, the subscriber can update the UI. However, if the publisher's thread is a background thread, the subscriber may be unable to directly update UI elements. In this case, the subscriber would need to schedule the updates on the UI thread using the Dispatcher class. +默认情况下,订阅者在发布者的线程上接收事件。如果发布者从 UI 线程发送事件,则订阅者可以更新 UI。但是,如果发布者的线程是后台线程,则订阅者可能无法直接更新 UI 元素。在这种情况下,订阅者需要使用 Dispatcher 类在 UI 线程上计划更新。 -The `PubSubEvent` provided with the Prism Library can assist by allowing the subscriber to automatically receive the event on the UI thread. The subscriber indicates this during subscription, as shown in the following code example. +Prism Library `PubSubEvent` 提供的 Prism 库可以通过允许订阅者在 UI 线程上自动接收事件来提供帮助。订阅服务器在订阅期间指示这一点,如下面的代码示例所示。 ```cs public class MainPageViewModel @@ -117,20 +115,19 @@ public class MainPageViewModel } ``` -The following options are available for `ThreadOption`: +以下选项可用于 `ThreadOption` : -- `PublisherThread`: Use this setting to receive the event on the publishers' thread. This is the default setting. -- `BackgroundThread`: Use this setting to asynchronously receive the event on a .NET Framework thread-pool thread. -- `UIThread`: Use this setting to receive the event on the UI thread. +- `PublisherThread`: 使用此设置可在发布商的话题上接收事件。这是默认设置。 +- `BackgroundThread`: 使用此设置可在 .NET Framework 线程池线程上异步接收事件。 +- `UIThread`: 使用此设置在 UI 线程上接收事件。 -> [!Note] -> In order for `PubSubEvent` to publish to subscribers on the UI thread, the `EventAggregator` must initially be constructed on the UI thread. +?> `PubSubEvent` 为了在 UI 线程上发布到订阅者,`EventAggregator` 最初必须在 UI 线程上构造。 -### Subscription Filtering +### 订阅筛选 -Subscribers may not need to handle every instance of a published event. In these cases, the subscriber can use the filter parameter. The filter parameter is of type `System.Predicate` and is a delegate that gets executed when the event is published to determine if the payload of the published event matches a set of criteria required to have the subscriber callback invoked. If the payload does not meet the specified criteria, the subscriber callback is not executed. +订阅者可能不需要处理已发布事件的每个实例。在这些情况下,订阅者可以使用 filter 参数。filter 参数的类型 `System.Predicate` 是一个委托,在发布事件时执行该委托,以确定已发布事件的有效负载是否与调用订阅者回调所需的一组条件匹配。如果负载不符合指定条件,则不会执行订阅者回调。 -Frequently, this filter is supplied as a lambda expression, as shown in the following code example. +通常,此筛选器以 lambda 表达式的形式提供,如下面的代码示例所示。 ```cs public class MainPageViewModel @@ -149,21 +146,19 @@ public class MainPageViewModel } ``` -> [!Note] -> The `Subscribe` method returns a subscription token of type `Prism.Events.SubscriptionToken` that can be used to remove a subscription to the event later. This token is particularly useful when you are using anonymous delegates or lambda expressions as the callback delegate or when you are subscribing the same event handler with different filters. +?> 该 `Subscribe` 方法返回一个类型的 `Prism.Events.SubscriptionToken` 订阅令牌,该令牌可用于稍后删除对事件的订阅。当您使用匿名委托或 lambda 表达式作为回调委托时,或者当您使用不同的筛选条件订阅同一事件处理程序时,此令牌特别有用。 -> [!Note] -> It is not recommended to modify the payload object from within a callback delegate because several threads could be accessing the payload object simultaneously. You could have the payload be immutable to avoid concurrency errors. +?> 建议不要从回调委托中修改有效负载对象,因为多个线程可以同时访问有效负载对象。您可以将有效负载设置为不可变的,以避免并发错误。 -### Subscribing Using Strong References +### 使用强引用订阅 -If you are raising multiple events in a short period of time and have noticed performance concerns with them, you may need to subscribe with strong delegate references. If you do that, you will then need to manually unsubscribe from the event when disposing the subscriber. +如果您在短时间内引发多个事件,并且注意到这些事件的性能问题,则可能需要订阅强大的委托引用。如果这样做,则需要在处置订阅者时手动取消订阅该事件。 -By default, `PubSubEvent` maintains a weak delegate reference to the subscriber's handler and filter on subscription. This means the reference that `PubSubEvent` holds on to will not prevent garbage collection of the subscriber. Using a weak delegate reference relieves the subscriber from the need to unsubscribe and allows for proper garbage collection. +默认情况下, `PubSubEvent` 维护对订阅者的处理程序和订阅筛选器的弱委托引用。这意味着 `PubSubEvent` 保留的引用不会阻止订阅者的垃圾回收。使用弱委托引用可使订阅者无需取消订阅,并允许进行适当的垃圾回收。 -However, maintaining this weak delegate reference is slower than a corresponding strong reference. For most applications, this performance will not be noticeable, but if your application publishes a large number of events in a short period of time, you may need to use strong references with PubSubEvent. If you do use strong delegate references, your subscriber should unsubscribe to enable proper garbage collection of your subscribing object when it is no longer used. +但是,维护此弱委托引用比相应的强引用慢。对于大多数应用程序,此性能并不明显,但如果应用程序在短时间内发布大量事件,则可能需要对 PubSubEvent 使用强引用。如果确实使用强委托引用,则订阅者应取消订阅,以便在不再使用订阅对象时对订阅对象进行适当的垃圾回收。 -To subscribe with a strong reference, use the `keepSubscriberReferenceAlive` parameter on the `Subscribe` method, as shown in the following code example. +若要使用强引用进行订阅,请使用 `Subscribe` 方法上的 `keepSubscriberReferenceAlive` 参数,如下面的代码示例所示。 ```cs public class MainPageViewModel @@ -183,16 +178,16 @@ public class MainPageViewModel } ``` -The `keepSubscriberReferenceAlive` parameter is of type `bool`: +`keepSubscriberReferenceAlive` 参数类型为 `bool` : -- When set to `true`, the event instance keeps a strong reference to the subscriber instance, thereby not allowing it to get garbage collected. For information about how to unsubscribe, see the section Unsubscribing from an Event later in this topic. -- When set to `false` (the default value when this parameter omitted), the event maintains a weak reference to the subscriber instance, thereby allowing the garbage collector to dispose the subscriber instance when there are no other references to it. When the subscriber instance gets collected, the event is automatically unsubscribed. +- 当设置为 `true` 时,事件实例将保留对订阅服务器实例的强引用,因此不允许它进行垃圾回收。有关如何取消订阅的信息,请参阅本主题后面的取消订阅事件部分。 +- 当设置为 `false` (省略此参数时的默认值) 时,该事件将保持对订阅服务器实例的弱引用,从而允许垃圾回收器在没有其他引用时释放订阅服务器实例。收集订阅服务器实例后,将自动取消订阅该事件。 -## Unsubscribing from an Event +## 取消订阅 Event -If your subscriber no longer wants to receive events, you can unsubscribe by using your subscriber's handler or you can unsubscribe by using a subscription token. +如果订阅者不想再接收事件,可以使用订阅者的处理程序取消订阅,也可以使用订阅令牌取消订阅。 -The following code example shows how to directly unsubscribe to the handler. +下面的代码示例演示如何直接取消订阅处理程序。 ```cs public class MainPageViewModel @@ -216,7 +211,7 @@ public class MainPageViewModel } ``` -The following code example shows how to unsubscribe with a subscription token. The token is supplied as a return value from the `Subscribe` method. +下面的代码示例演示如何使用订阅令牌取消订阅。令牌作为 `Subscribe` 方法的返回值提供。 ```cs public class MainPageViewModel diff --git a/docs/index.html b/docs/index.html index f26ca8a..c3c0ff9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -32,10 +32,15 @@ } } + + - - + + + + + diff --git a/docs/introduction.md b/docs/index.md similarity index 80% rename from docs/introduction.md rename to docs/index.md index a5f7912..a43a4dd 100644 --- a/docs/introduction.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # Prism 简介 -> Prism 是一个用于构建松耦合、可维护且可测试的 XAML 应用程序的框架,适用于 WPF、.NET MAUI、Uno平台和 Xamarin Forms。每个平台都有独立的发布版本,并且会在不同的时间线上独立开发。Prism 提供了一组设计模式的实现,这些模式在撰写结构良好、易于维护的 XAML 应用程序中非常有用,包括 MVVM、依赖注入、命令、EventAggregator 等。Prism 的核心功能是基于跨编译的 .NET Standard 和 .NET 4.5/4.8 库的共享代码库。需要针对特定平台的内容将在目标平台的各个库中实现。Prism 还针对目标平台与这些模式的集成提供了大量支持。例如,Prism for Xamarin Forms 允许您使用可进行单元测试的导航抽象,但该层叠在平台概念和API上以实现导航,这样您就可以充分利用平台本身的导航提供的功能,但这一切都以 MVVM 的方式进行。 +> Prism 是一个用于构建松耦合、可维护且可测试的 XAML 应用程序的框架,适用于 WPF、.NET MAUI、Uno平台和 Xamarin Forms。每个平台都有独立的发布版本,并且会在不同的时间线上独立开发。Prism 提供了一组设计模式的实现,这些模式在撰写结构良好、易于维护的 XAML 应用程序中非常有用,包括 MVVM、依赖注入、命令、事件聚合器等。Prism 的核心功能是基于跨平台编译的 .NET Standard 和 .NET 4.5/4.8 库的共享代码库,需要针对特定平台的内容将在目标平台的各个库中实现。Prism 还针对目标平台与这些模式的集成提供了大量支持。例如,Prism for Xamarin Forms 允许您使用可进行单元测试的导航抽象,但该层叠在平台概念和API上以实现导航,这样您就可以充分利用平台本身的导航提供的功能,但这一切都以 MVVM 的方式进行。 > Prism 9代表了应用程序开发人员的重大飞跃,大量的焦点集中在统一所有平台的 API上。这将为开发人员解锁许多可能性,允许他们将代码从旧的应用程序进行迭代或从一个应用程序开发平台过渡到另一个,最大化代码重用并消除开发成本。 @@ -19,6 +19,8 @@ The Prism license that contains the terms and conditions can be found at https://cdn.prismlibrary.com/downloads/prism_license.pdf ``` +[下载Pirsm完整许可证](https://cdn.prismlibrary.com/downloads/prism_license.pdf) + # 商业增值许可证 商业增值许可证为开发人员提供了一系列额外的软件包。撰写文档时,这将包括: - Prism.Plugin.Popups(.NET MAUI) diff --git a/docs/mvvm/bindablebase.md b/docs/mvvm/bindablebase.md index bbda040..0abfb6a 100644 --- a/docs/mvvm/bindablebase.md +++ b/docs/mvvm/bindablebase.md @@ -20,7 +20,7 @@ public class ViewAViewModel : BindableBase ### 为什么使用 SetProperty -您可能想知道,为什么要使用 `SetProperty` ?毕竟,你不能自己调用RaisePropertyChanged吗?简短的回答是你可以。但是,这通常是不可取的,因为您将丢失内置的 EqualityComparer,这有助于确保如果多次调用具有相同值 `INotifyPropertyChanged` 的 setter,则仅在事件第一次更改时触发 `PropertyChanged` 事件。 +您可能想知道,为什么要使用 `SetProperty` ?毕竟,你不能自己调用RaisePropertyChanged吗?简短的回答是你可以。但是,这通常是不建议的,因为您将丢失内置的 EqualityComparer,这有助于确保如果多次调用具有相同值 `INotifyPropertyChanged` 的 setter,则仅在事件第一次更改时触发 `PropertyChanged` 事件。 ```cs public class ViewAViewModel : BindableBase diff --git a/docs/mvvm/viewmodel-locator.md b/docs/mvvm/viewmodel-locator.md index 71ba797..1706018 100644 --- a/docs/mvvm/viewmodel-locator.md +++ b/docs/mvvm/viewmodel-locator.md @@ -1,12 +1,12 @@ -# Using the ViewModelLocator +# 使用 ViewModelLocator -The `ViewModelLocator` is used to wire the `DataContext` of a view to an instance of a ViewModel using a standard naming convention. +用于 `ViewModelLocator` 使用标准命名约定将 `DataContext` 视图连接到 ViewModel 的实例。 -The Prism `ViewModelLocator` has an `AutoWireViewModel` attached property, that when set to `true` calls the `AutoWireViewModelChanged` method in the `ViewModelLocationProvider` class to resolve the ViewModel for the view, and then set the view’s data context to an instance of that ViewModel. This behavior is on by default: if you don't want that for your view, you need to opt-out. +Prism `ViewModelLocator` 具有附加 `AutoWireViewModel` 属性,当设置为 `true` 调用 `ViewModelLocationProvider` 类中 `AutoWireViewModelChanged` 的方法以解析视图的 ViewModel,然后将视图的数据上下文设置为该 ViewModel 的实例时。默认情况下,此行为处于启用状态:如果您不希望视图出现此行为,则需要选择退出。 -> In the case of **WPF**, this is only the default behavior when using **region navigation** and ```IDialogService```. If you are using **view injection**, your view will need to opt-in. +> 对于 **WPF**, 这只是使用 **区域导航** 和 ```IDialogService```. 如果您使用的是 **视图注入**, 您的视图将需要选择加入。 -Use the `AutoWireViewModel` attached property as below. Set the value to ```False``` to opt-out and ```True``` to explicitly opt-in. +使用附加的 `AutoWireViewModel` 属性如下所示. 将值设置为 ```False``` 选择退出, 置为 ```True``` 显式选择加入. ```xml ``` -To locate a ViewModel, the `ViewModelLocationProvider` first attempts to resolve the ViewModel from any mappings that may have been registered by the `ViewModelLocationProvider.Register` method (See [Custom ViewModel Registrations](#custom-viewmodel-registrations)). If the ViewModel cannot be resolved using this approach, the `ViewModelLocationProvider` falls back to a convention-based approach to resolve the correct ViewModel type. +若要查找 ViewModel, `ViewModelLocationProvider` 首先尝试从 `ViewModelLocationProvider.Register` 该方法可能已注册的任何映射中解析 ViewModel (请参阅 [自定义 ViewModel 注册](#custom-viewmodel-registrations))。 如果无法使用此方法解析 ViewModel,则 `ViewModelLocationProvider` 回退到基于约定的方法来解析正确的 ViewModel 类型。 -This convention assumes: +本约定假定: -- that ViewModels are in the same assembly as the view types -- that ViewModels are in a `.ViewModels` child namespace -- that views are in a `.Views` child namespace -- that ViewModel names correspond with view names and end with "ViewModel." +- ViewModel 与视图类型位于同一程序集中 +- ViewModel 位于 `.ViewModels` 子命名空间中 +- 视图位于 `.Views` 子命名空间中 +- ViewModel 名称与视图名称相对应,并以 "ViewModel." 结尾 -> [!Note] -> The `ViewModelLocationProvider` can be found in the `Prism.Mvvm` namespace in the **Prism.Core** NuGet package. The `ViewModelLocator` can be found in the `Prism.Mvvm` namespace in the platform specific packages (**Prism.WPF**, **Prism.Forms**) NuGet package. +?> `ViewModelLocationProvider` 可以在 **Prism.Core** NuGet 包的 `Prism.Mvvm` 命名空间中找到。`ViewModelLocator` 可以在特定于平台的(**Prism.WPF**, **Prism.Forms**) NuGet包的 `Prism.Mvvm` 命名空间中找到。 -> [!Note] -> The ViewModelLocator is required, and automatically applied to every View, when developing with Xamarin.Forms as it is responsible for providing the correct instance of the `INavigationService` to the ViewModel. When developing a Xamarin.Forms app, the `ViewModelLocator` is opt-out only. +?> 使用 Xamarin.Forms 进行开发时,ViewModelLocator 是必需的,并自动应用于每个视图,因为它负责向 ViewModel 提供正确的 `INavigationService` 实例。开发 Xamarin.Forms 应用时, `ViewModelLocator` 只能选择退出。 -> [!Video https://www.youtube.com/embed/I_3LxBdvJi4] + -## Change the Naming Convention +## 更改命名约定 -If your application does not follow the `ViewModelLocator` default naming convention, you can change the convention to meet the requirements of your application. The `ViewModelLocationProvider` class provides a static method called `SetDefaultViewTypeToViewModelTypeResolver` that can be used to provide your own convention for associating views to view models. +如果应用程序不遵循 `ViewModelLocator` 默认命名约定,则可以更改约定以满足应用程序的要求。该 `ViewModelLocationProvider` 类提供了一个名为的 `SetDefaultViewTypeToViewModelTypeResolver` 静态方法,该方法可用于提供您自己的约定,用于将视图关联到视图模型。 -To change the `ViewModelLocator` naming convention, override the `ConfigureViewModelLocator` method in the `App.xaml.cs` class. Then provide your custom naming convention logic in the `ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver` method. +若要更改 `ViewModelLocator` 命名约定,请重写 `App.xaml.cs` 类中 `ConfigureViewModelLocator` 的方法。然后在 `ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver` 方法中提供自定义命名约定逻辑。 ```cs protected override void ConfigureViewModelLocator() @@ -53,13 +51,13 @@ protected override void ConfigureViewModelLocator() } ``` -> [!Video https://www.youtube.com/embed/o4ibaOFvfww] + -## Custom ViewModel Registrations +## 自定义 ViewModel 注册 -There may be instances where your app is following the `ViewModelLocator` default naming convention, but you have a number of ViewModels that do not follow the convention. Instead of trying to customize the naming convention logic to conditionally meet all your naming requirments, you can register a mapping for a ViewModel to a specific view directly with the `ViewModelLocator` by using the `ViewModelLocationProvider.Register` method. +在某些情况下,你的应用可能遵循 `ViewModelLocator` 默认命名约定,但你有许多 ViewModel 不遵循该约定。您可以直接使用 `ViewModelLocator` 的 `ViewModelLocationProvider.Register` 方法将 ViewModel 的映射注册到特定视图,而不是尝试自定义命名约定逻辑以有条件地满足所有命名要求。 -The following examples show the various ways to create a mapping between a view called `MainWindow` and a ViewModel named `CustomViewModel`. +下面的示例演示在名为 `MainWindow` 的视图和名为 `CustomViewModel` 的 ViewModel 之间创建映射的各种方法。 **Type / Type** @@ -85,19 +83,17 @@ ViewModelLocationProvider.Register(() => Container.Resolve(); ``` -> [!Note] -> Registering your ViewModels directly with the `ViewModelLocator` is faster than relying on the default naming convention. This is because the naming convention requires the use of reflection, while a custom mapping provides the type directly to the `ViewModelLocator`. +?> 直接向 `ViewModelLocator` 注册 ViewModel 比依赖默认命名约定更快。这是因为命名约定要求使用反射,而自定义映射则直接向 `ViewModelLocator` . -> [!Important] -> The `viewTypeName` parameter must be the fully qualifyied name of the view's Type (`Type.ToString()`). Otherwise the mapping will fail. +!> 该 `viewTypeName` 参数必须是视图的 Type (`Type.ToString()`) 的完全限定名称。否则,映射将失败。 -> [!Video https://www.youtube.com/embed/phMc4OuKs58] + -## Control how ViewModels are Resolved +## 控制 ViewModel 的解析方式 -By default, the `ViewModelLocator` will use the DI container you have chosen to create your Prism application to resolve ViewModels. However, if you ever have the need to customize how ViewModels are resolved or change the resolver altogether, you can achieve this by using the `ViewModelLocationProvider.SetDefaultViewModelFactory` method. +默认情况下, `ViewModelLocator` 将使用您选择的 DI 容器来创建 Prism 应用程序来解析 ViewModel。但是,如果您需要自定义 ViewModel 的解析方式或完全更改解析器,则可以使用该 `ViewModelLocationProvider.SetDefaultViewModelFactory` 方法实现此目的。 -This example shows how you might change the container used for resolving the ViewModel instances. +此示例演示如何更改用于解析 ViewModel 实例的容器。 ```cs protected override void ConfigureViewModelLocator() @@ -111,7 +107,7 @@ protected override void ConfigureViewModelLocator() } ``` -This is an example of how you might check the type of the view the ViewModel is being created for, and performing logic to control how the ViewModel is created. +下面是一个示例,说明如何检查为其创建 ViewModel 的视图类型,以及如何执行逻辑来控制 ViewModel 的创建方式。 ```cs protected override void ConfigureViewModelLocator() diff --git a/docs/navigation/navigation-parameters.md b/docs/navigation/navigation-parameters.md index 897f9dd..61fd9d2 100644 --- a/docs/navigation/navigation-parameters.md +++ b/docs/navigation/navigation-parameters.md @@ -1,10 +1,10 @@ # INavigationParameters -The Navigation Parameters are a way that you can pass state, options, or other values during Navigation events. This includes both [Page based Navigation](xref:Navigation.INavigationParameters) as well as [Region based navigation](xref:Navigation.Regions.GettingStarted). The Navigation Parameters can be comprised entirely from the query string in your Navigation Uri, or from an instance of the `NavigationParameters`. It can even merge the two allowing you to combine query string parameters and parameters from an instance of the `NavigationParameters`. This will be done for you automatically by Prism in the Navigation Service. +导航参数是一种在导航事件期间传递状态、选项或其他值的方法。这包括 [基于页面的导航](xref:Navigation.INavigationParameters) 以及 [基于区域的导航](xref:Navigation.Regions.GettingStarted)。 导航参数可以完全由导航 Uri 中的查询字符串组成,也可以由 `NavigationParameters` .它甚至可以将两者合并,允许您组合查询字符串参数和来自 `NavigationParameters` .这将由 Prism 在导航服务中自动为您完成。 -In Prism 9.0 the Navigation Parameters and interface are entirely shared from the Prism.Core across all Navigation paradigms and platforms. +在 Prism 9.0 中,导航参数和界面在所有导航范式和平台上完全从 Prism.Core 共享。 -## Creating Navigation Parameters +## 创建导航参数 ```cs new NavigationParameters @@ -14,7 +14,7 @@ new NavigationParameters } ``` -As you will notice when creating an instance of the NavigationParameters you can add values of various types. +正如您在创建 NavigationParameters 实例时会注意到的那样,您可以添加各种类型的值。 ```cs new NavigationParameters @@ -24,23 +24,23 @@ new NavigationParameters } ``` -While at first it may appear that `INavigationParameters` is just an `IDictionary`, it is in fact an `IEnumerable>`. This means that you have the ability to overload the keys adding multiple values to the NavigationParameters with a single key. +虽然乍一看似乎 `INavigationParameters` 只是一个 `IDictionary` ,但实际上它是一个 `IEnumerable>` .这意味着,您可以使用单个键重载键,将多个值添加到 NavigationParameters。 -## Accessing Navigation Parameters +## 访问导航参数 -Depending on what you need to get from the Navigation Parameters you may want to call one of the following APIs. +根据您需要从导航参数中获取的内容,您可能需要调用以下 API 之一。 ### Getting a Single Value -To access a single value from the Navigation Parameters you should use the `GetValue` method like: +若要从导航参数中访问单个值,应使用如下 `GetValue` 方法: ```cs Title = parameters.GetValue("Title"); ``` -### Get a value if the key exists +### 如果键存在,则获取值 -To access a value only if the key exists you can use the `TryGetValue` method like: +若要仅在键存在时访问值,可以使用如下 `TryGetValue` 方法: ```cs if (parameters.TryGetValue("Title", out var title)) @@ -49,9 +49,9 @@ if (parameters.TryGetValue("Title", out var title)) } ``` -### Getting multiple values +### 获取多个值 -To access multiple values you can use the `GetValues` method. This will return an empty list if no values were provided. +若要访问多个值,可以使用该 `GetValues` 方法。如果未提供任何值,这将返回一个空列表。 ```cs var colors = parameters.GetValues("SelectedColors"); diff --git a/docs/navigation/page-navigation.md b/docs/navigation/page-navigation.md index 97c3e49..e4a5ea8 100644 --- a/docs/navigation/page-navigation.md +++ b/docs/navigation/page-navigation.md @@ -1,6 +1,6 @@ # Page Navigation -Every Platform is unique and has it's own set of requirements and ways it handles navigation. Page based Navigation is not a concept used by Prism within either WPF or Uno Platform. If you are building an app with either of these platforms you should see the documentation for [Region Navigation](xref:Navigation.Regions.GettingStarted). Otherwise you will want to see the documentation specific to the platform you are building with. As Page based Navigation is not supported globally across all platforms the abstractions are different making the documentation for these areas of your application platform specific. +每个平台都是独一无二的,并且有自己的一套要求和处理导航的方式。基于页面的导航不是 Prism 在 WPF 或 Uno Platform 中使用的概念。如果要使用这些平台中的任何一个构建应用程序,则应查看 [区域导航](xref:Navigation.Regions.GettingStarted) 的文档。否则,您将需要查看特定于您正在构建的平台的文档。由于并非所有平台都支持基于页面的导航,因此抽象是不同的,因此应用程序平台的这些领域的文档是特定的。 - [Prism for .NET MAUI](xref:Platforms.Maui.Navigation.GettingStarted) - [Prism for Xamarin.Forms](xref:Platforms.XamarinForms.Navigation.Basics) \ No newline at end of file diff --git a/docs/navigation/regions/basic-region-navigation.md b/docs/navigation/regions/basic-region-navigation.md index ab9d0db..5c9a7b7 100644 --- a/docs/navigation/regions/basic-region-navigation.md +++ b/docs/navigation/regions/basic-region-navigation.md @@ -1,6 +1,3 @@ ---- -uid: Navigation.Regions.BasicRegionNavigation ---- # Basic Region Navigation Both view injection and view discovery can be considered to be limited forms of navigation. View injection is a form of explicit, programmatic navigation and view discovery is a form of implicit or deferred navigation. However, in Prism, regions have been extended to support a more general notion of navigation, based on URIs and an extensible navigation mechanism. diff --git a/docs/navigation/regions/confirming-navigation.md b/docs/navigation/regions/confirming-navigation.md index 9cc9c6c..f907651 100644 --- a/docs/navigation/regions/confirming-navigation.md +++ b/docs/navigation/regions/confirming-navigation.md @@ -1,6 +1,3 @@ ---- -uid: Navigation.Regions.ConfirmingNavigation ---- # Confirming Navigation You will often find that you will need to interact with the user during a navigation operation, so that the user can confirm or cancel it. In many applications, for example, the user may try to navigate while in the middle of entering or editing data. In these situations, you may want to ask the user whether he or she wants to save or discard the data that has been entered before continuing to navigate away from the page, or whether the user wants to cancel the navigation operation altogether. Prism supports these scenarios via the **IConfirmNavigationRequest** interface. diff --git a/docs/navigation/regions/controlling-view-lifetime.md b/docs/navigation/regions/controlling-view-lifetime.md index eecd118..8cba906 100644 --- a/docs/navigation/regions/controlling-view-lifetime.md +++ b/docs/navigation/regions/controlling-view-lifetime.md @@ -1,6 +1,3 @@ ---- -uid: Navigation.Regions.ControllingViewLifetime ---- # Controlling View Lifetime ## IRegionMemberLifetime diff --git a/docs/navigation/regions/index.md b/docs/navigation/regions/index.md index 9fb7884..71eab9a 100644 --- a/docs/navigation/regions/index.md +++ b/docs/navigation/regions/index.md @@ -1,28 +1,27 @@ # Getting Started -> [!NOTE} -> As a part of the Prism 9.0 initiative, a lot of focus has been given to unifying the Prism API across all of the supported platforms. As a result the Region Abstractions are no longer platform specific. This greatly simplifies what you must learn as you transition from one platform to another. As an added benefit this means that you can now build applications that share ViewModels across WPF, .NET MAUI and Uno Platform and even port your Xamarin.Forms application code to these other platforms. +?> 作为 Prism 9.0 计划的一部分,我们非常重视在所有受支持的平台上统一 Prism API。因此,区域抽象不再是特定于平台的。这大大简化了从一个平台过渡到另一个平台时必须学习的内容。作为额外的好处,这意味着你现在可以生成跨 WPF、.NET MAUI 和 Uno 平台共享 ViewModel 的应用程序,甚至可以将 Xamarin.Forms 应用程序代码移植到这些其他平台。 -As the user interacts with a rich client application, its user interface (UI) will be continuously updated to reflect the current task and data that the user is working on. The UI may undergo considerable changes over time as the user interacts with and completes various tasks within the application. The process by which the application coordinates these UI changes is often referred to as *navigation*. This topic describes how to implement navigation for composite Model-View-ViewModel (MVVM) applications using the Prism library. +当用户与富客户端应用程序交互时,其用户界面 (UI) 将不断更新,以反映用户正在处理的当前任务和数据。随着用户与应用程序交互并完成应用程序中的各种任务,UI 可能会随着时间的推移而发生相当大的变化。应用程序协调这些 UI 更改的过程通常称为导航。本主题介绍如何使用 Prism 库实现复合模型-视图-视图模型 (MVVM) 应用程序的导航。 -Frequently, navigation means that certain controls in the UI are removed, while other controls are added. In other cases, navigation may mean that the visual state of one or more existing controls is updated. As an example,as the state of the app changes, some controls may be simply hidden or collapsed, while other controls are shown or expanded. Navigation may also mean that the data being displayed by a control is updated to reflect the current state of the application. For example, in a master-detail scenario, the data displayed in the detail view will be updated based on the currently selected item in the master view. All of these scenarios can be considered navigation because the user interface is updated to reflect the user's current task and the application's current state. +通常,导航意味着删除 UI 中的某些控件,同时添加其他控件。在其他情况下,导航可能意味着更新一个或多个现有控件的可视状态。例如,当应用状态发生变化时,某些控件可能只是隐藏或折叠,而其他控件则显示或展开。导航还可能意味着控件显示的数据将更新以反映应用程序的当前状态。例如,在大从-从场景下,将根据大图中当前选定的项目更新明细视图中显示的数据。所有这些方案都可以被视为导航,因为用户界面已更新以反映用户的当前任务和应用程序的当前状态。 -Navigation within an application can result from the user's interaction with the UI (via mouse events or other UI gestures) or from the application itself as a result of internal logic-driven state changes. In some cases, navigation may involve very simple UI updates that require no custom application logic. In other cases, the application may implement complex logic to programmatically control navigation to ensure that certain business rules are enforced—for example, the application may not allow the user to navigate away from a certain form without first ensuring that the data entered is correct. +应用程序中的导航可以由用户与 UI 的交互(通过鼠标事件或其他 UI 手势)产生,也可以由应用程序本身作为内部逻辑驱动的状态更改的结果。在某些情况下,导航可能涉及非常简单的 UI 更新,不需要自定义应用程序逻辑。在其他情况下,应用程序可以实现复杂的逻辑,以编程方式控制导航,以确保强制执行某些业务规则,例如,应用程序可能不允许用户在未首先确保输入的数据正确的情况下离开特定窗体。 -Implementing the required navigation behavior in a Windows Presentation Foundation (WPF) or UNO application can often be relatively straightforward because it provides direct support for navigation. However, navigation can be more complex to implement in applications that use the Model-View-ViewModel (MVVM) pattern or in composite applications that use multiple loosely-coupled modules. Prism provides guidance on implementing navigation in these situations. +在 Windows Presentation Foundation (WPF) 或 UNO 应用程序中实现所需的导航行为通常相对简单,因为它提供对导航的直接支持。但是,在使用模型-视图-视图模型 (MVVM) 模式的应用程序或使用多个松散耦合模块的复合应用程序中实现导航可能更复杂。Prism 提供了在这些情况下实现导航的指导。 -## Navigation in Prism +## Prism 中的导航 -Navigation is defined as the process by which the application coordinates changes to its UI as a result of the user's interaction with the application or internal application state changes. +导航被定义为应用程序协调由于用户与应用程序的交互或内部应用程序状态更改而对其 UI 的更改的过程。 -| Navigation Type | Description | +| 导航类型 | 描述 | |-----------------|-------------| | State Based | Navigation accomplished via state changes to existing controls in the visual tree. | | View Based | Navigation accomplished via the addition or removal of elements from the visual tree. | -Prism provides guidance on implementing both styles of navigation, focusing on the case where the application is using the Model-View-ViewModel (MVVM) pattern to separate the UI (encapsulated in the view) from the presentation logic and data (encapsulated in the view model). +Prism 提供了有关实现这两种导航样式的指导,重点介绍应用程序使用 Model-View-ViewModel (MVVM) 模式将 UI(封装在视图中)与表示逻辑和数据(封装在视图模型中)分开的情况。 -| Topics | Description | +| 主题 | 描述 | |-----------------------------------|-------------| | [Basic Region Navigation](xref:Navigation.Regions.BasicRegionNavigation) | Get started with the Prism navigation system. | | [Confirming Navigation](xref:Navigation.Regions.ConfirmingNavigation) | Learn how to allow the user to interact with the navigation system. | diff --git a/docs/navigation/regions/navigation-existing-views.md b/docs/navigation/regions/navigation-existing-views.md index dc55323..014d29c 100644 --- a/docs/navigation/regions/navigation-existing-views.md +++ b/docs/navigation/regions/navigation-existing-views.md @@ -1,6 +1,3 @@ ---- -uid: Navigation.Regions.NavigationExistingViews ---- # Navigating to Existing Views Frequently, it is more appropriate for the views in your application to be re-used, updated, or activated during navigation, instead of replaced by a new view. This is often the case where you are navigating to the same type of view but need to display different information or state to the user, or when the appropriate view is already available in the UI but needs to be activated (that is, selected or made top-most). diff --git a/docs/navigation/regions/navigation-journal.md b/docs/navigation/regions/navigation-journal.md index df1b817..e4be6e1 100644 --- a/docs/navigation/regions/navigation-journal.md +++ b/docs/navigation/regions/navigation-journal.md @@ -1,6 +1,3 @@ ---- -uid: Navigation.Regions.NavigationJournal ---- # Using the Navigation Journal The **NavigationContext** class provides access to the region navigation service, which is responsible for coordinating the sequence of operations during navigation within a region. It provides access to the region in which navigation is taking place, and to the navigation journal associated with that region. The region navigation service implements the **IRegionNavigationService**, which is defined as follows. diff --git a/docs/navigation/regions/passing-parameters.md b/docs/navigation/regions/passing-parameters.md index e920317..8bace61 100644 --- a/docs/navigation/regions/passing-parameters.md +++ b/docs/navigation/regions/passing-parameters.md @@ -1,6 +1,3 @@ ---- -uid: Navigation.Regions.PassingParameters ---- # Passing Parameters During Navigation To implement the required navigational behavior in your application, you will often need to specify additional data during navigation request than just the target view name. The **NavigationContext** object provides access to the navigation URI, and to any parameters that were specified within it or externally. You can access the **NavigationContext** from within the **IsNavigationTarget**, **OnNavigatedFrom**, and **OnNavigatedTo** methods. diff --git a/docs/navigation/regions/region-adapters.md b/docs/navigation/regions/region-adapters.md index eef379b..ef30f08 100644 --- a/docs/navigation/regions/region-adapters.md +++ b/docs/navigation/regions/region-adapters.md @@ -1,5 +1 @@ ---- -uid: Navigation.Regions.RegionAdapter ---- - # Region Adapter diff --git a/docs/navigation/regions/region-behaviors.md b/docs/navigation/regions/region-behaviors.md index 0b389cc..d3a5923 100644 --- a/docs/navigation/regions/region-behaviors.md +++ b/docs/navigation/regions/region-behaviors.md @@ -1,5 +1 @@ ---- -uid: Navigation.Regions.RegionBehaviors ---- - # Region Behaviors diff --git a/docs/navigation/regions/region-manager.md b/docs/navigation/regions/region-manager.md index 66eff71..a82f3b3 100644 --- a/docs/navigation/regions/region-manager.md +++ b/docs/navigation/regions/region-manager.md @@ -1,5 +1 @@ ---- -uid: Navigation.Regions.RegionManager ---- - # Region Manager diff --git a/docs/navigation/regions/view-viewmodel-participation.md b/docs/navigation/regions/view-viewmodel-participation.md index e0ea473..0957598 100644 --- a/docs/navigation/regions/view-viewmodel-participation.md +++ b/docs/navigation/regions/view-viewmodel-participation.md @@ -1,6 +1,3 @@ ---- -uid: Navigation.Regions.ViewViewModelParticipation ---- # View and View Model Participation in Navigation Frequently, the views and view models in your application will want to participate in navigation. The **INavigationAware** interface enables this. You can implement this interface on the view or (more commonly) the view model. By implementing this interface, your view or view model can opt-in to participate in the navigation process. diff --git a/docs/platforms/wpf/getting-started.md b/docs/platforms/wpf/getting-started.md index 91089f7..52e5d37 100644 --- a/docs/platforms/wpf/getting-started.md +++ b/docs/platforms/wpf/getting-started.md @@ -1,7 +1,3 @@ ---- -uid: Platforms.Wpf.GettingStarted ---- - # Getting Started Getting started with Prism is pretty easy. Follow the steps below and you will be up and running quickly with the start of a modular and easy to maintain app. diff --git a/docs/platforms/wpf/interactivity/event-to-command.md b/docs/platforms/wpf/interactivity/event-to-command.md index adab4aa..581ebf7 100644 --- a/docs/platforms/wpf/interactivity/event-to-command.md +++ b/docs/platforms/wpf/interactivity/event-to-command.md @@ -1,7 +1,3 @@ ---- -uid: Platforms.Wpf.Interactivity.EventToCommand ---- - # Binding Events to Commands The ```InvokeCommandAction``` class provides a convenient way to, in XAML, "bind" events to ```ICommand``` properties according to the MVVM paradigm of avoiding code behind.