csharpshare.com
Show / Hide Table of Contents

入门

Gitee仓库 Prism-Documentation-CH 时间 2023-1-23

Prism入门非常容易。遵循以下步骤,您将快速启动并运行一个模块化且易于维护的应用程序。

本指南假定您对WPF应用程序项目的结构有所了解,并且对C#也有一定的了解。如果您对模型-视图-视图模型(MVVM)模式比较熟悉也会有很大帮助,而且WPF很容易支持该模式。如果您并不了解以上内容,请考虑先花点时间对其进行一些研究。

安装Nuget包

首先在Visual Studio中创建一个全新的WPF应用程序。接下来是安装合适的nuget包。在使用哪个容器来管理依赖项这一点上,您需要做出一个选择。而在本文档中Unity将是选择的容器。请参见下面的列表。

Package Container Version
Prism.Unity Unity 5.11.1
Prism.DryIoc DryIoc 4.0.7

注意:无需显式安装任何其他依赖项。安装上述软件包之一还将负责安装容器的软件包以及共享的Prism软件包。

安装Nuget

覆写现有的应用程序对象

入门的下一步是继承新创建的WPF项目中包含的Application对象。打开App.xaml并将标准WPF Application类替换为Prism的```PrismApplication``类。

<prism:PrismApplication
    x:Class="WpfApp1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApp1"
    xmlns:prism="http://prismlibrary.com/">
    <Application.Resources>
    </Application.Resources>
</prism:PrismApplication>

在上面的代码片段中,请注意添加了第6行来定义命名空间,并且更新了App对象使其派生自PrismApplication。接下来,打开app.xaml.cs的代码文件并更新类定义。

不要忘记从PrismApplication标签中删除StartupUri属性,否则您就会得到两个window实例。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using Prism.Unity;

namespace WpfApp1
{
    public partial class App : PrismApplication
    {
    }
}

在PrismApplication中定义了一对必须首先实现的抽象方法:RegisterTypes和CreateShell。

RegisterTypes

此函数用于注册所有的应用程序依赖项。例如您可能有一个接口可以从某种持久存储中读取客户数据,而它的实现是使用某种数据库。它可能看起来像这样:

public interface ICustomerStore
{
    List<string> GetAll();
}

public class DbCustomerStore : ICustomerStore
{
    public List<string> GetAll()
    {
        // return list from db
    }
}

应用程序中依赖于客户数据的对象(例如视图模型)将需要一个ICustomerStore对象。在App.RegisterTypes函数中,每当对象依赖于ICustomerStore时,都会进行注册以创建DbCustomerStore。

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.Register<Services.ICustomerStore, Services.DbCustomerStore>();
    // register other needed services here
}

IContainerRegistry还有其他可以用于注册接口的函数。比如RegisterInstance将针对接口注册已创建的对象实例,其中注册接口的实现实际上是单例的。一个类似的方法是RegisterSingleton,它将在建立依赖关系时而不是之前便创建一个实例。值得注意的是,Container也可以在没有事先注册的情况下解析具体类型。

CreateShell

第二个要实现的方法是CreateShell方法。这个方法将创建应用程序的主窗口。其中App类的Container属性应该用来创建窗口,因为它会处理所有的依赖项。

public partial class App : PrismApplication
{
    // RegisterTypes function is here

    protected override Window CreateShell()
    {
        var w = Container.Resolve<MainWindow>();
        return w;
    }
}

此时,应用程序可以构建并运行,应该如下所示:

第一次运行应用程序

现在这已经是一个Prism应用程序了,虽然目前还没有太多的内容,但Prism可以提供很多帮助,例如将应用程序分解为可管理的块、导航和实现MVVM模式。

视图模型

WPF为使用MVVM模式进行了很好的配置,Prism在这方面也会有很大帮助。Prism有一个基类,用于处理INotifyPropertyChanged基础结构,该基础结构会将视图模型中的更改发布到视图中。此外还有一些其他类可以使从视图模型中处理按钮变得更简单,而不是在代码中编写事件处理程序。

首先需要向视图中添加一些控件,跳转到MainWindow.xaml并添加以下<Grid>标记作为<MainWindow>的内容。

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <ListView
            ItemsSource="{Binding Customers}"
            SelectedItem="{Binding SelectedCustomer}"
        />
        <Button
            Grid.Row="1" Width="80" Height="40"
            Command="{Binding CommandLoad}"
            Content="LOAD"
        />
    </Grid>

上面将添加一个新的列表视图,它将显示客户名称列表和一个加载列表的按钮。

要记住的重要一点是,每次有一个Binding时,都会有一个到该视图所关联的视图模型上的链接。

为了帮助您完成入门指南的这一部分,还需要在项目中设置上面所显示内容的服务。在项目的根目录中创建一个Services文件夹,并在该文件夹中创建CustomerStore.cs文件并添加以下代码:

    public interface ICustomerStore
    {
        List<string> GetAll();
    }

    public class DbCustomerStore : ICustomerStore
    {
        public List<string> GetAll()
        {
            return new List<string>()
            {
                "cust 1",
                "cust 2",
                "cust 3",
            };
        }
    }

在App.xaml.cs文件中,确保RegisterTypes包含以下内容:

    containerRegistry.Register<Services.ICustomerStore, Services.DbCustomerStore>();

创建视图模型

首先,在项目的根目录下创建一个名为ViewModels的文件夹。请您务必使用该准确名称,因为稍后在讨论视图模型解析时会需要它。

项目文件夹结构

在ViewModels文件夹中,创建了一个名为MainWindowViewModel的类,其中使用这个准确名字的原因将在后面展示。Prism有一个名为BindableBase的类,它被用作所有视图模型的基础,MainWindowViewModel也将继承于它。

using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp1.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private Services.ICustomerStore _customerStore = null;

        public MainWindowViewModel(Services.ICustomerStore customerStore)
        {
            _customerStore = customerStore;
        }


        public ObservableCollection<string> Customers { get; private set; } =
            new ObservableCollection<string>();


        private string _selectedCustomer = null;
        public string SelectedCustomer
        {
            get => _selectedCustomer;
            set
            {
                if (SetProperty<string>(ref _selectedCustomer, value))
                {
                    Debug.WriteLine(_selectedCustomer ?? "no customer selected");
                }
            }
        }

        private DelegateCommand _commandLoad = null;
        public DelegateCommand CommandLoad =>
            _commandLoad ?? (_commandLoad = new DelegateCommand(CommandLoadExecute));

        private void CommandLoadExecute()
        {
            Customers.Clear();
            List<string> list = _customerStore.GetAll();
            foreach (string item in list)
                Customers.Add(item);
        }
    }
}

解释一下这里发生了什么。MainWindowViewModel依赖于ICustomerStore接口,因此该接口必须在App.RegisterTypes中注册,以便其实现可以由依赖容器处理。其中有一个Customers属性绑定到用户界面中的ListView上,还有一个SelectedCustomer绑定到ListView中的当前选择项上。

还有一个实现ICommand接口的CommandLoad对象,它有一个Execute方法,会在每当用户点击按钮时调用。Prism使用了DelegateCommand类实现了ICommand接口,它允许传递委托来处理实现ICommand接口。在CommandLoad这种情况中,CommandLoadExecute函数会作为委托传入,于是现在每当WPF绑定系统尝试执行ICommand.Execute时,CommandLoadExecute都会被调用。

有关DelegateCommand的更多详细信息,请参阅 命令。

使用ViewModelLocator

现在有一个视图和一个视图模型,但它们是如何链接在一起的?该功能开箱即用,因为Prism有一个ViewModelLocator,它使用约定来确定视图模型的正确类,用其依赖关系实例化它,并将其附加到视图的DataContext。

默认约定是将所有视图放在Views文件夹中,将视图模型放在ViewModels文件夹中。

  • WpfApp1.Views.MainWindow => WpfApp1.ViewModels.MainWindowViewModel
  • WpfApp1.Views.OtherView => WpfApp1.ViewModels.OtherViewModel

这是可配置的,并且可以添加不同的解析逻辑。

为此,视图和视图模型必须正确地位于其正确的名称空间中。下面是它的屏幕截图:

ViewModelLocator项目结构

单击此处了解有关ViewModelLocator的详细信息。

如果你出于某些原因不想使用此功能,则必须在视图中选择关闭。您可以按如下方式在XAML中管理此项:

<Window
    ...
    xmlns:prism="http://prismlibrary.com/"
    prism:ViewModelLocator.AutoWireViewModel="False"
    >

	<!-- ui controls here -->
</Window>
本文导航
返回顶部 ©2022-2023 csharpshare.com    冀ICP备2022026743号-1     公安备案图标 冀公网安备 13052902000206号     Icons by Icons8