WPF之Prism框架

1.Region(区域管理)

在最常见的开发模式当中, 我们去设计某个页面的时候, 实际上界面元素在设计的时候已经被固定。
举个简单的例子,当我们去设计如下页面, 它包含Header、Menu、Content内容。

 1.1定义Region

可以使用XAML或代码创建定义Region

XAML:

<Window
    x:Class="HT.PrismApp.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Width="525"
    Height="350"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="50" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <ContentControl Grid.Row="0" prism:RegionManager.RegionName="HeaderRegion" />
        <Grid Grid.Row="1" ShowGridLines="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <ContentControl Grid.Column="0" prism:RegionManager.RegionName="MenuRegion" />
            <ContentControl Grid.Column="1" prism:RegionManager.RegionName="ContentRegion" />
        </Grid>
    </Grid>
</Window>

C#定义:RegionManager.SetRegionName("控件名","区域名称");

1.2注册区域视图

using HT.PrismApp.Views;
using Prism.Mvvm;
using Prism.Regions;

namespace HT.PrismApp.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        public MainWindowViewModel(IRegionManager regionManager)
        {
            regionManager.RegisterViewWithRegion("HeaderRegion",typeof(HeaderView));
            regionManager.RegisterViewWithRegion("MenuRegion", typeof(MenuView));
            regionManager.RegisterViewWithRegion("ContentRegion", typeof(ContentView));
        }
    }
}

2.ViewModelLocator

在WPF当中,需要为View与ViewModel建立连接, 我们需要找到View的DataContext, 如下所示:

XAML的方式:

 <UserControl.DataContext>
        <.../>
 </UserControl.DataContext>

代码的方式:

    public partial class ViewA : UserControl
    {
        public ViewA()
        {
            InitializeComponent();
            this.DataContext = null; //设定
        }
    }

在Prism当中, 你可以基于命名约定, 便能够轻松的将View/ViewModel建议关联。如下所示:

假设你已经为项目添加Views和ViewModels文件夹。此时, 你的页面为ViewA, 则对应的ViewModel名称为 ViewAViewModel。

错误命名例子:假如你的页面为PageView,对应的ViewModel名称为PageViewModel,而不是PageViewViewModel。

3.MVVM

众所周知, 如果你了解WPF当中的ICommand, INotifyPropertyChanged的作用, 就会发现
众多框架都是基于这些进行扩展, 实现其通知、绑定、命令等功能。

3.1通知

Prism继承Prism.Mvvm.BindableBase,进行调用RaisePropertyChanged方法即可。

3.2命令

Prism继承Prism.Mvvm.BindableBase,进行使用DelegateCommand即可。

3.3拓展

对于单个Command而言, 只是触发单个对应的功能, 而复合命令是Prism当中非常强大的功能, CompositeCommand简单来说是一个父命令, 它可以注册N个子命令。

using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace HT.PrismApp.ViewModels
{
    public class ContentViewModel : BindableBase
    {
        public ContentViewModel() 
        {
            ACommamd = new DelegateCommand(() =>
            {
                Title += "ACommamd";
            });
            BCommamd = new DelegateCommand(() =>
            {
                Title += "BCommamd";
            });
            //复合命令
            ClickAllCommand = new CompositeCommand();
            ClickAllCommand.RegisterCommand(ACommamd);
            ClickAllCommand.RegisterCommand(BCommamd);
        }
        private string title="测试";
        public string Title
        {
            get
            {
                return title;
            }
            set
            {
                title = value;
                RaisePropertyChanged(nameof(Title));
            }
        }
        public DelegateCommand ACommamd;
        public DelegateCommand BCommamd;
     
        public DelegateCommand SaveCommamd
        {
            get
            {
                return new DelegateCommand(() =>
                {

                });
            }
        }
        public CompositeCommand ClickAllCommand { get; set; }
    }
}

3.4IEventAggregator(事件通讯)

发布:

using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace HT.PrismApp.ViewModels
{
    public class ContentViewModel : BindableBase
    {
        private readonly IEventAggregator _eventAggregator;
        public ContentViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
        }
        private string msg;
        public string Msg
        {
            get
            {
                return msg;
            }
            set
            {
                msg = value;
                RaisePropertyChanged(nameof(Msg));
            }
        }
        public DelegateCommand SendCommamd
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    _eventAggregator.GetEvent<PubSubEvent<string>>().Publish(Msg);
                });
            }
        }
    }
}

订阅: 

using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HT.PrismApp.ViewModels
{
    public class HeaderViewModel : BindableBase
    {
        public HeaderViewModel(IEventAggregator eventAggregator)
        {
            eventAggregator.GetEvent<PubSubEvent<string>>().Subscribe(ReceiveMessage, ThreadOption.PublisherThread, false, msg =>
            {
                //过滤
                return true;
            });
        }
        private void ReceiveMessage(string msg)
        {
            Text = msg;
        }
        private string text;
        public string Text
        {
            get
            {
                return text;
            }
            set
            {
                text = value;
                RaisePropertyChanged(nameof(Text));
            }
        }
    }
}

4.Navigation(导航)

4.1导航的基本条件:注册显示区域、注册导航页面

(1)注册导航

using HT.PrismApp.ViewModels;
using HT.PrismApp.Views;
using Prism.Ioc;
using System.Windows;

namespace HT.PrismApp
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //注册导航
            containerRegistry.RegisterForNavigation<ContentView>();
            containerRegistry.RegisterForNavigation<MenuView>();
            //指定VieModel
            //containerRegistry.RegisterForNavigation<ContentView, ContentViewModel>();
            //containerRegistry.RegisterForNavigation<MenuView, MenuViewModel>();
        }
    }
}

2.使用导航

using HT.PrismApp.Views;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace HT.PrismApp.ViewModels
{
    public class HeaderViewModel : BindableBase
    {
        private IRegionManager _regionManager;
        public HeaderViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
        }
        public DelegateCommand NavigationA
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    //使用导航
                    _regionManager.RequestNavigate("ContentRegion", nameof(ContentView));

                });
            }
        }
        public DelegateCommand NavigationB
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    //使用导航
                    _regionManager.RequestNavigate("ContentRegion", nameof(MenuView));
                });
            }
        }
    }
}

拓展:

        public DelegateCommand NavigationA
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    //带参数,ViewModel继承INavigationAware
                    //OnNavigatedTo: 导航完成前, 此处可以传递过来的参数以及是否允许导航等动作的控制。
                    //IsNavigationTarget: 调用以确定此实例是否可以处理导航请求。否则新建实例
                    //OnNavigatedFrom: 当导航离开当前页时, 类似打开A, 再打开B时, 该方法被触发。

                    //还有可以继承IConfirmNavigationRequest
                    //拦截导航请求
                    //public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
                    //{
                    //    bool result = true;

                    //    if (MessageBox.Show("确认导航?", "温馨提示", MessageBoxButton.YesNo) == MessageBoxResult.No)
                    //        result = false;

                    //    //通过回调当前返回的确认结果,决定是否启动该导航
                    //    continuationCallback(result);
                    //}
                    var param = new NavigationParameters();
                    param.Add("Parameter", param);
                    _regionManager.RequestNavigate("ContentRegion", nameof(ContentView), param);
                    //类似URL地址传递参数
                    //_regionManger.RequestNavigate("ContentRegion", $"{nameof(ContentView)}?id=1&Name=xiaoming");
                });
            }
        }

3.Navigation Journal导航日志

using HT.PrismApp.Views;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace HT.PrismApp.ViewModels
{
    public class HeaderViewModel : BindableBase
    {
        private IRegionManager _regionManager;
        private IRegionNavigationJournal _journal;
        public HeaderViewModel(IRegionManager regionManager, IRegionNavigationJournal journal)
        {
            _regionManager = regionManager;
            _journal = journal;
        }
        public DelegateCommand NavigationA
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    _regionManager.RequestNavigate("ContentRegion", nameof(ContentView), args =>
                    {
                        //***导航日志
                        _journal = args.Context.NavigationService.Journal;
                    });
                });
            }
        }
        public DelegateCommand NavigationB
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    //使用导航
                    _regionManager.RequestNavigate("ContentRegion", nameof(MenuView), args =>
                    {
                        //***导航日志
                        _journal = args.Context.NavigationService.Journal;
                    });
                });
            }
        }
        public DelegateCommand GoBack
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    _journal.GoBack();
                });
            }
        }
        public DelegateCommand GoForward
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    _journal.GoForward();
                });
            }
        }
    }
}

5.Dialog(对话框)

对话框实际上是我们应用程序经常用到的一个功能, 类如: Show、ShowDialog。
可以弹出一个我们指定的窗口, 仅此而已, 那么在Prism当中, Dialog指的是什么?

Prism提供了一组对话服务, 封装了常用的对话框组件的功能, 例如:

  • RegisterDialog/IDialogService (注册对话及使用对话)
  • 打开对话框传递参数/关闭对话框返回参数
  • 回调通知对话结果

5.1创建对话框,通常是一组用户控件 ,并且实现 IDialogAware

using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;

namespace HT.PrismApp.ViewModels
{
    public class MessageDialogViewModel : BindableBase, IDialogAware
    {
        public string Title => "对话框服务";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }
        /// <summary>
        /// 对话框关闭时
        /// </summary>
        public void OnDialogClosed()
        {
        }
        /// <summary>
        /// 对话框打开时
        /// </summary>
        /// <param name="parameters"></param>
        public void OnDialogOpened(IDialogParameters parameters)
        {

        }
        public DelegateCommand SaveCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
                });
            }
        }
        public DelegateCommand CancelCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
                });
            }
        }
    }
}

5.2注册对话框 RegisterDialog

using HT.PrismApp.ViewModels;
using HT.PrismApp.Views;
using Prism.Ioc;
using System.Windows;

namespace HT.PrismApp
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterDialog<MessageDialog, MessageDialogViewModel>();
        }
    }
}

5.3使用IDialogService接口 Show/ShowDialog 方法调用对话框

using HT.PrismApp.Views;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace HT.PrismApp.ViewModels
{
    public class HeaderViewModel : BindableBase
    {
        private IRegionManager _regionManager;
        private IRegionNavigationJournal _journal;
        private IDialogService _dialogService;
        public HeaderViewModel(IRegionManager regionManager, IRegionNavigationJournal journal, IDialogService dialogService)
        {
            _regionManager = regionManager;
            _journal = journal;
            _dialogService= dialogService;
        }
        public DelegateCommand NavigationA
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    _regionManager.RequestNavigate("ContentRegion", nameof(ContentView), args =>
                    {
                        //***导航日志
                        _journal = args.Context.NavigationService.Journal;
                    });
                });
            }
        }
        public DelegateCommand NavigationB
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    //使用导航
                    _regionManager.RequestNavigate("ContentRegion", nameof(MenuView), args =>
                    {
                        //***导航日志
                        _journal = args.Context.NavigationService.Journal;
                    });
                });
            }
        }
        public DelegateCommand GoBack
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    _journal.GoBack();
                });
            }
        }
        public DelegateCommand GoForward
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    _journal.GoForward();
                });
            }
        }
        public DelegateCommand OpenDialog
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    _dialogService.ShowDialog(nameof(MessageDialog));
                });
            }
        }
    }
}

  • 12
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WPF Prism框架是一个面向对象的框架,用于开发模块化、可扩展的WPF应用程序,它基于MVVM设计模式和依赖注入技术。该框架的主要目的是能够轻松地实现可插拔的模块,公共的服务、组件和工具类的共享,同时也提供了灵活的路由、事件聚合、模块加载、导航和命令处理等机制。使用WPF Prism框架可以快速地开发出灵活的WPF应用程序,从而提高代码质量和开发效率,减少代码的维护难度。 WPF Prism框架具有以下的特点: 1. 扩展性:可以轻松地添加新的模块、服务和组件,同时也可以快速替换现有的组件。 2. 可重用性:提供了丰富的公共组件、服务和工具类,从而可以提高代码的可重用性。 3. 灵活性:提供了灵活的路由、事件聚合、模块加载和导航等机制,能够更好地满足应用程序的需求。 4. 易用性:提供了一套完整的MVVM设计模式和依赖注入技术的实践方案,从而能够更好地组织应用程序的逻辑。 总之,WPF Prism框架是一个强大的工具,能够让我们更好地开发WPF应用程序,提高代码质量和开发效率,实现可插拔的模块化和可扩展性,同时也具有灵活性和易用性。 ### 回答2: WPF Prism框架是一种面向MVVM模式的开源框架,它帮助开发人员使用模块化的方式构建可扩展、可重用和易于维护的WPF应用程序。该框架主要由Microsoft和模式仲裁者团队开发和维护,它借鉴了许多现代的软件开发理念,比如IoC容器、依赖注入和事件聚合器等。 WPF Prism框架的核心思想是将应用程序分解为许多可独立维护和扩展的模块。这些模块可以基于业务逻辑、UI、数据或任何其他特征进行分组。在该框架中,模块由各种名为“组件”的构建块组成。这些组件包括视图(View)、视图模型(ViewModel)、服务(Service)、模型(Model)等。通过基于这些组件的开发,可以实现具有高度可伸缩性和可重用性的应用程序。 为了实现这种模块化开发和组件化架构,WPF Prism框架提供了一些重要的工具和特性。例如,在该框架中可以使用依赖注入容器(如Unity)来管理组件及其依赖关系。此外,该框架还提供了一些基于事件的消息机制,可方便地实现模块间的交互和通信。 总体来说,WPF Prism框架是一种利用开源技术实现企业级应用程序开发的最佳选择。它具有良好的模块化、组件化和可扩展性特性,可以在实现复杂WPF应用程序时提高开发效率和代码质量。 ### 回答3: WPF Prism是一个基于WPF框架,它为大型应用程序提供了一种组织、设计和部署的方式。它旨在帮助开发者构建可扩展、可维护和可测试的WPF应用程序。 WPF Prism采用了面向模块的编程思想,它将整个应用程序划分为多个模块,每个模块都包含自己的逻辑和用户界面。这种模块化设计使得应用程序易于扩展和维护,同时也简化了开发流程。 WPF Prism同时提供了一组强大的工具和功能,如依赖注入、命令模式和事件聚合等,这些功能让WPF应用程序更加易于开发和测试。它还提供了一个强大的导航和区域管理系统,开发者可以使用这些系统来管理不同部分的用户界面和功能。 总之,WPF Prism是一个优秀的框架,它为开发者提供了全面的工具和功能,使得构建WPF应用程序变得更加容易和高效。它的结构良好、可扩展性强,而且可以充分利用WPF的强大功能。无论是大型企业应用程序还是小型桌面应用程序,WPF Prism都是一个理想的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值