Loading

Prism 中区域、模块化、导航功能、对话服务、发布订阅的简单使用

本文演示了 Prism 框架在 WPF 编程中的几个基本功能
环境:Visual Studio 2022

内容

介绍 Prism 几个基本功能,包括区域、模块化、导航功能、对话服务、发布订阅

区域

  1. 可以在 XMAL 中定义某 ContentControl 为 Prism 的区域,并在App中注册模块:
// 这个区域的名字为 ContentRegion
<ContentControl prism:RegionManager.RegionName="ContentRegion" />

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterForNavigation<ViewC>();
}
  1. 在 ViewModel 的构造函数中传入区域管理器的属性参数:
private readonly IRegionManager regionManager;

public MainViewModel(IRegionManager regionManager)
{
    this.regionManager = regionManager;
}
  1. 在绑定的方法中即可通过区域管理器设置其显示的内容:
// 按钮 绑定了Open方法 传入一个string参数
<Button Margin="10" Command="{Binding OpenCommand}" CommandParameter="ModuleA" Content="Open ModuleA" />

private void Open(string obj)
{
    // 可以在调用这个控件时给其传入参数
    NavigationParameters keys = new NavigationParameters();
    // 使用的是键值对的方式
    keys.Add("Title", "Hello ModuleA");
    // callback是回调函数,在执行完更改区域后会调用,可以获取该命令执行结果
    regionManager.Regions["ContentRegion"].RequestNavigate(obj, callback =>
    {
        if ((bool)callback.Result)
        {
            journal = callback.Context.NavigationService.Journal;
        }
    }, keys);
}
  1. 在区域内要这样实现:
public class ModuleAViewModel : BindableBase, IConfirmNavigationRequest
{
    public ModuleAViewModel()
    {

    }

    private string title;

    public string Title
    {
        get { return title; }
        set { title = value; RaisePropertyChanged(); }
    }

    // 每次重新导航的时候,该实例是否重用
    public bool IsNavigationTarget(NavigationContext navigationContext)
    {
        return true;
    }
    
    // 当从该模块离开时
    public void OnNavigatedFrom(NavigationContext navigationContext) { }

    // 当进入该模块时
    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        // 获取传入的参数
        navigationContext.Parameters.TryGetValue<string>("Title", out title);
    }

    // 确认是否相应导航请求
    public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
    {
        bool res = false;
        if (MessageBox.Show("是否跳转页面?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
        {
            res = true;
        }
        continuationCallback(res);
    }
}

模块化

  1. 通过强引用导入模块
// 在依赖中引用 dll 并在 App 中重写该方法
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
    // 添加引用-> 添加模块
    moduleCatalog.AddModule<ModuleAProfile>();
    moduleCatalog.AddModule<ModuleBProfile>();
    base.ConfigureModuleCatalog(moduleCatalog);
}
  1. 指定目录动态加载,重写该方法,返回指定的目录
protected override IModuleCatalog CreateModuleCatalog()
{
    // 通过目录加载
    return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
}
  1. 在编写模块时,必须添加XXXProfile文件,并实现IModule接口
public class ModuleAProfile : IModule
{
    public void OnInitialized(IContainerProvider containerProvider)
    {

    }

    // 注册模块
    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<ModuleA, ModuleAViewModel>();
    }
}

导航功能

// 声明一个日志对象
private IRegionNavigationJournal journal;

public MainViewModel(IRegionManager regionManager)
{
    // 实例化
    this.journal = new RegionNavigationJournal();
}

// 上一步
if (journal.CanGoBack)
{
    journal.GoBack();
}

// 记录journal
if ((bool)callback.Result)
{
    journal = callback.Context.NavigationService.Journal;
}

对话服务

  1. 在 ViewModel 的构造函数中传入对话服务的属性参数:
private readonly IDialogService dialogService;

public MainViewModel(IDialogService dialogService)
{
    this.dialogService = dialogService;
}
  1. 在对话框组件的 ViewModel 中实现 IDialogAware 接口
public class ViewDViewModel : IDialogAware
{
    public string Title { get; set; }

    public event Action<IDialogResult> RequestClose;

    public bool CanCloseDialog()
    {
        return true;
    }

    public void OnDialogClosed()
    {

    }

    public void OnDialogOpened(IDialogParameters parameters)
    {

    }
}
  1. 在app中注册对话框组件
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterDialog<ViewD, ViewDViewModel>();
}
  1. 使用对话服务
private void Alert()
{
    // 其重载的方法也可以传入参数和回调函数
    dialogService.ShowDialog("ViewD");
}

发布订阅

  1. 在 ViewModel 的构造函数中传入发布订阅的属性参数:
private readonly IEventAggregator eventAggregator;

public MainViewModel(IEventAggregator eventAggregator)
{
    this.eventAggregator = eventAggregator;
}
  1. 新建一个类,实现发布订阅的接口,表示传递什么类型的消息
// 表示传递 string 消息
public class EventMessage : PubSubEvent<string>
{
}
  1. 订阅消息
// Subscribe订阅 UnSubscribe 取消订阅
eventAggregator.GetEvent<EventMessage>().Subscribe(message =>
{
    MessageBox.Show(message);
});
  1. 发布消息
eventAggregator.GetEvent<EventMessage>().Publish("Hello");

总结

主要总结了一下区域、模块化、导航功能、对话服务、发布订阅的简单使用,还需要多写多熟练。

作者:chanstic
出处:Prism 中区域、模块化、导航功能、对话服务、发布订阅的简单使用
本作品采用「CC BY-NC-SA 4.0」许可协议进行许可

posted @ 2023-04-03 21:13  chanstic  阅读(704)  评论(0编辑  收藏  举报