WPF Prism

一、简介

WPF Prism是一套由微软模式和实践团队(Microsoft Patterns & Practices Team)开发的面向Windows Presentation Foundation (WPF) 的框架。该框架目标是带来可重用、可插入、可测试的模块化代码,以及保持松耦合的应用程序代码。WPF Prism框架用于帮助开发人员构建具有高度模块化、可测试、可维护且易于扩展的WPF桌面应用程序。Prism利用依赖注入 (DI) 容器来实现模块化、命令、事件聚合 (EA)、导航、区域等功能,以提供一致性的解决方案。

二、模块化开发

设计良好的应用程序应该是由若干松耦合的模块组成的,每个模块都能独立、可移植、可重用,并且易于测试。Prism框架通过依赖注入(DI)容器实现模块化,代码创建对象时只需指定对象基类或接口,DI容器会自动寻找并构造该对象所依赖的实例,并返回完整的对象。

实际上,在Prism框架上,模块等同于程序集,而且每个程序集都必须包含一个派生自 IModule 接口的模块类。这个类需要实现 IModule.Initialize 方法,通过该方法可以向程序注入一些功能。下面介绍一些重要的基本模块初始化,以及在模块之间共享数据。

1. 模块初始化

使用Prism框架,您可以使用以下代码,初始化模块

    
// MyApp.ModulA.dll
public class ModulA : IModule
{
    public void Initialize()
    {
        // 初始化视图和服务所需的代码
    }
}

// App.xaml.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    // 使用RegisterType注册服务
    containerRegistry.RegisterType<IService, Service>();
}

protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
    // 使用ModuleCatalog添加模块
    moduleCatalog.AddModule(typeof(ModulA));
}
    

2. 模块间共享数据

在模块之间,有时需要共享数据。例如,ModulA 模块需要提供数据,以便其他模块使用,您可以使用以下代码,向其他需要该数据的模块添加服务

    
// MyApp.ModulA.dll
public class ModulA : IModule
{
    // 公共数据
    public static IData Data = new Data();

    public void Initialize()
    {
        // 注册服务
        containerRegistry.RegisterInstance<IData>(Data);
    }
}

// MyApp.ModulB.dll
public class ModulB : IModule
{
    public ModulB(IData data)
    {
        var myData = data as Data;// 编写代码,以便使用Data服务
    }

    public void Initialize()
    {
        // 初始化...
    }
}

// App.xaml.cs
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
    moduleCatalog.AddModule<ModulA>();// 我们不需要在此处添加ModulB,因为ModulB是自动加载的
}
    

三、依赖注入

依赖注入(Dependency Injection)是一种编程方法,通过该方法,我们可以创建松耦合、可测试且可重用的代码。您只需定义接口或基类,然后使用Prism框架,自动寻找并创建该接口或基类的实现。依赖注入是Prism框架的核心,贯穿整个框架。

1. 构造函数注入

构造函数注入是最简单的依赖注入方法。在该模式下,您仅需使用 Container.Resolve 方法创建实例。以下代码演示使用构造函数注入实例化对象

    
// 定义接口和实现
public interface IService
{
    void DoSomething();
}

public class Service : IService
{
    public void DoSomething()
    {
        Console.WriteLine("Hello World!");
    }
}

// Main
var service = Container.Resolve<IService>();
service.DoSomething();
    

2. 属性注入

属性注入是一种广泛应用的依赖注入方法。该方法在对象创建完成之后,通过反射操作,向对象的属性自动注入相应的实现实例。通过Prism框架,我们使用 [Dependency] 特性注入属性。

    
// 定义接口和实现
public interface IService
{
    void DoSomething();
}

public class Service : IService
{
    public void DoSomething()
    {
        Console.WriteLine("Hello World!");
    }
}

// Main
class MainViewModel
{
    [Dependency]
    public IService Service { get; set; } // 必须是公共属性

    public MainViewModel()
    {

    }

    public void DoSomething()
    {
        Service.DoSomething();
    }
}

// 在Main函数中初始化
var mainViewModel = new MainViewModel();
Container.BuildUp(mainViewModel); // 执行依赖注入
mainViewModel.DoSomething();
    

四、命令

在Prism框架中,命令(Command)是一项非常强大的功能,它可以轻松解决许多典型的WPF应用程序需求,例如向视图添加命令,创建分离的命令对象,将命令绑定到控件或 ViewModel 等。

在Prism框架内部,命令使用 DelegateCommand / DelegateCommand<T> 类来实现。例如,以下是使用 DelegateCommand 类创建命令的示例代码

    
// 定义命令
public DelegateCommand MyCommand { get; private set; }

public MainViewModel()
{
    // 添加命令
    MyCommand = new DelegateCommand(Execute, CanExecute);
}

void Execute()
{
    Debug.WriteLine("执行命令");
}

bool CanExecute()
{
    return true;
}
    

五、导航

在WPF应用程序中,导航(navigation)是一项关键的功能。该功能使我们能够通过显示给定的页面或视图,让用户在视觉上移动,以便在不同的屏幕之间进行切换。在Prism框架中,导航需要两个主要组件: 导航器(NavigationService)和导航目的地(NavigationTarget)。

导航器处理导航请求,而导航目的地则对导航请求进行响应。

    
// 在模块中添加导航
public class AppModule : IModule
{
    public AppModule(INavigationService navigationService)
    {
        this.navigationService = navigationService;
    }

    public void Initialize()
    {
        navigationService.RegisterViewWithRegion("MainRegion", typeof(ViewA));
    }
}

// 在ViewModel中实现导航
public class ViewAViewModel : BindableBase // BindableBase是Prism中的一个基类,实现了 INotifyPropertyChanged
{
    public ViewAViewModel(INavigationService navigationService)
    {
        NavigateCommand = new DelegateCommand(() => navigationService.Navigate("ViewB"));
    }

    private DelegateCommand _navigateCommand;
    public DelegateCommand NavigateCommand
    {
        get => _navigateCommand;
        set => SetProperty(ref _navigateCommand, value);
    }
}

// 在View中,创建一个按钮并将它绑定到导航命令

六、区域

在WPF Prism中,区域(Region)是指一个可以在其中显示一个或多个视图的窗体区域。您可以将区域视为桌面应用程序中的子窗口,因为您可以将视图放入区域,并在不同的区域中切换视图。

以下示例演示如何创建区域,并将视图添加到该区域

    
// App.xaml.cs
public partial class App : PrismApplication
{
    protected override Control CreateShell()
    {
        return Container.Resolve();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register();
    }

    protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
    {
        moduleCatalog.AddModule();
    }

    protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
    {
        base.ConfigureRegionAdapterMappings(regionAdapterMappings);
        regionAdapterMappings.RegisterMapping(typeof(StackPanel), Container.Resolve());
    }
}

// 注册StackPanel区域和Adapter
public class StackPanelRegion : Region
{
}

public class StackPanelRegionAdapter : IRegionAdapter
{
    public IRegion Initialize(object regionTarget, string regionName)
    {
        var region = new StackPanelRegion();
        region.Name = regionName;

        var stackpanel = regionTarget as StackPanel;
        RegionManager.SetRegionManager(stackpanel, ContainerLocator.Current.Resolve());
        RegionManager.UpdateRegions();
        return region;
    }

    public bool IsAdaptable(object regionTarget)
    {
        return regionTarget is StackPanel;
    }

    public void AdaptView(object regionTarget)
    {

    }
}

// 主模块
public class MainModule : IModule
{
    public void Initialize()
    {
        IRegionManager regionManager = ServiceLocator.Current.GetInstance();
        regionManager.RegisterViewWithRegion("TopArea", typeof(TopView));
    }
}

// 创建具有指定名称的区域,以及包含“TopArea”名称的StackPanel控件


    

七、总结

通过本文的介绍,我们可以看到WPF Prism框架的强大功能:模块化开发、依赖注入、命令、导航和区域。通过这些功能,我们可以轻松地构建可扩展、可重用、可测试的WPF应用程序。当然,除了本文介绍的这些内容之外,WPF Prism框架还提供了许多其他的功能和特性,如事件聚合(event aggregator),属性注入、策略等。

原创文章,作者:YRTWS,如若转载,请注明出处:https://www.506064.com/n/372072.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
YRTWSYRTWS
上一篇 2025-04-23 18:08
下一篇 2025-04-24 06:40

相关推荐

  • 使用ReoGrid操作Excel的WPf应用

    本文将详细阐述如何使用ReoGrid来操作Excel,重点介绍在WPF应用程序中使用ReoGrid的方法及注意点。 一、ReoGrid简介 ReoGrid是一个基于.NET的开源组…

    编程 2025-04-27
  • 深入探讨WPF Menu控件

    WPF Menu控件是一种经常使用的界面元素,它能够在WPF应用程序中创建菜单和子菜单。这种控件是极其灵活和多样化的,可以使用户轻松地导航、查找和执行应用程序的不同部分。在这篇文章…

    编程 2025-04-20
  • WPF TreeView数据绑定详解

    一、绑定方式 在使用WPF TreeView进行数据绑定的时候,常见的几种方式有以下几种。 1. 使用静态数据源 <TreeView> <TreeViewItem…

    编程 2025-04-12
  • 如何实现WPF进度条动态更新

    一、WPF进度条简介 WPF(Windows Presentation Foundation)是一种用于在Windows操作系统上创建和部署富客户端应用程序的技术,是.NET Fr…

    编程 2025-04-12
  • wpf依赖属性详解

    一、依赖属性wpf 在WPF中,依赖属性是其最重要的特性之一。它们是可扩展的属性系统,使您可以创建具有特定依赖属性行为的自定义属性。如果您有经验,您可能已经了解WPF的依赖属性,但…

    编程 2025-02-25
  • WPF Prism:一个优秀的WPF应用程序框架

    一、简介 WPF(Windows Presentation Foundation)是一个用于构建Windows客户端应用程序的框架,它提供了许多可定制的UI组件和数据绑定功能。但是…

    编程 2025-01-21
  • 使用prism.js使代码高亮更加美观

    一、什么是prism.js Prism是一个轻量级,简洁优美且非常易于使用的语法高亮插件。Prism可以在完全自定义的同时提供很多不错的默认主题。Prism适用于任何语言的编码,包…

    编程 2025-01-11
  • 深入了解 WPF Slider

    一、概述 WPF Slider 是 WPF 中的一个非常常用的控件,它通常用来实现用户界面中的滑动条。通过拖动滑块,用户可以快速调整某个数值的大小。 WPF Slider 控件支持…

    编程 2025-01-02
  • WPF StringFormat — WPF字符串格式化

    一、概述 WPF字符串格式化是使用特定格式将数据转换为字符串的过程。在 WPF 中,我们可以使用 StringFormat 来格式化字符串。StringFormat 可以用于各种 …

    编程 2025-01-02
  • WPF模板最佳实践: 如何提高页面流量和转化率

    一、网站页面的设计方法 网站是展示企业形象和服务的门面,一个好的页面设计可以有效地提高网站的用户体验和转化率。在WPF模板的设计中,我们需要考虑以下几点: 1、鲜明的色彩 色彩的选…

    编程 2025-01-01

发表回复

登录后才能评论