当前位置:   article > 正文

WPF之Prism框架_wpf prism开发框架示例

wpf prism开发框架示例

1.Region(区域管理)

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

 1.1定义Region

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

XAML:

  1. <Window
  2. x:Class="HT.PrismApp.Views.MainWindow"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:prism="http://prismlibrary.com/"
  6. Width="525"
  7. Height="350"
  8. prism:ViewModelLocator.AutoWireViewModel="True">
  9. <Grid ShowGridLines="True">
  10. <Grid.RowDefinitions>
  11. <RowDefinition Height="50" />
  12. <RowDefinition />
  13. </Grid.RowDefinitions>
  14. <ContentControl Grid.Row="0" prism:RegionManager.RegionName="HeaderRegion" />
  15. <Grid Grid.Row="1" ShowGridLines="True">
  16. <Grid.ColumnDefinitions>
  17. <ColumnDefinition Width="100" />
  18. <ColumnDefinition Width="*" />
  19. </Grid.ColumnDefinitions>
  20. <ContentControl Grid.Column="0" prism:RegionManager.RegionName="MenuRegion" />
  21. <ContentControl Grid.Column="1" prism:RegionManager.RegionName="ContentRegion" />
  22. </Grid>
  23. </Grid>
  24. </Window>

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

1.2注册区域视图

  1. using HT.PrismApp.Views;
  2. using Prism.Mvvm;
  3. using Prism.Regions;
  4. namespace HT.PrismApp.ViewModels
  5. {
  6. public class MainWindowViewModel : BindableBase
  7. {
  8. public MainWindowViewModel(IRegionManager regionManager)
  9. {
  10. regionManager.RegisterViewWithRegion("HeaderRegion",typeof(HeaderView));
  11. regionManager.RegisterViewWithRegion("MenuRegion", typeof(MenuView));
  12. regionManager.RegisterViewWithRegion("ContentRegion", typeof(ContentView));
  13. }
  14. }
  15. }

2.ViewModelLocator

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

XAML的方式:

  1. <UserControl.DataContext>
  2. <.../>
  3. </UserControl.DataContext>

代码的方式:

  1. public partial class ViewA : UserControl
  2. {
  3. public ViewA()
  4. {
  5. InitializeComponent();
  6. this.DataContext = null; //设定
  7. }
  8. }

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个子命令。

  1. using Prism.Commands;
  2. using Prism.Mvvm;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows.Input;
  9. namespace HT.PrismApp.ViewModels
  10. {
  11. public class ContentViewModel : BindableBase
  12. {
  13. public ContentViewModel()
  14. {
  15. ACommamd = new DelegateCommand(() =>
  16. {
  17. Title += "ACommamd";
  18. });
  19. BCommamd = new DelegateCommand(() =>
  20. {
  21. Title += "BCommamd";
  22. });
  23. //复合命令
  24. ClickAllCommand = new CompositeCommand();
  25. ClickAllCommand.RegisterCommand(ACommamd);
  26. ClickAllCommand.RegisterCommand(BCommamd);
  27. }
  28. private string title="测试";
  29. public string Title
  30. {
  31. get
  32. {
  33. return title;
  34. }
  35. set
  36. {
  37. title = value;
  38. RaisePropertyChanged(nameof(Title));
  39. }
  40. }
  41. public DelegateCommand ACommamd;
  42. public DelegateCommand BCommamd;
  43. public DelegateCommand SaveCommamd
  44. {
  45. get
  46. {
  47. return new DelegateCommand(() =>
  48. {
  49. });
  50. }
  51. }
  52. public CompositeCommand ClickAllCommand { get; set; }
  53. }
  54. }

3.4IEventAggregator(事件通讯)

发布:

  1. using Prism.Commands;
  2. using Prism.Events;
  3. using Prism.Mvvm;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Input;
  10. namespace HT.PrismApp.ViewModels
  11. {
  12. public class ContentViewModel : BindableBase
  13. {
  14. private readonly IEventAggregator _eventAggregator;
  15. public ContentViewModel(IEventAggregator eventAggregator)
  16. {
  17. _eventAggregator = eventAggregator;
  18. }
  19. private string msg;
  20. public string Msg
  21. {
  22. get
  23. {
  24. return msg;
  25. }
  26. set
  27. {
  28. msg = value;
  29. RaisePropertyChanged(nameof(Msg));
  30. }
  31. }
  32. public DelegateCommand SendCommamd
  33. {
  34. get
  35. {
  36. return new DelegateCommand(() =>
  37. {
  38. _eventAggregator.GetEvent<PubSubEvent<string>>().Publish(Msg);
  39. });
  40. }
  41. }
  42. }
  43. }

订阅: 

  1. using Prism.Events;
  2. using Prism.Mvvm;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace HT.PrismApp.ViewModels
  9. {
  10. public class HeaderViewModel : BindableBase
  11. {
  12. public HeaderViewModel(IEventAggregator eventAggregator)
  13. {
  14. eventAggregator.GetEvent<PubSubEvent<string>>().Subscribe(ReceiveMessage, ThreadOption.PublisherThread, false, msg =>
  15. {
  16. //过滤
  17. return true;
  18. });
  19. }
  20. private void ReceiveMessage(string msg)
  21. {
  22. Text = msg;
  23. }
  24. private string text;
  25. public string Text
  26. {
  27. get
  28. {
  29. return text;
  30. }
  31. set
  32. {
  33. text = value;
  34. RaisePropertyChanged(nameof(Text));
  35. }
  36. }
  37. }
  38. }

4.Navigation(导航)

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

(1)注册导航

  1. using HT.PrismApp.ViewModels;
  2. using HT.PrismApp.Views;
  3. using Prism.Ioc;
  4. using System.Windows;
  5. namespace HT.PrismApp
  6. {
  7. /// <summary>
  8. /// Interaction logic for App.xaml
  9. /// </summary>
  10. public partial class App
  11. {
  12. protected override Window CreateShell()
  13. {
  14. return Container.Resolve<MainWindow>();
  15. }
  16. protected override void RegisterTypes(IContainerRegistry containerRegistry)
  17. {
  18. //注册导航
  19. containerRegistry.RegisterForNavigation<ContentView>();
  20. containerRegistry.RegisterForNavigation<MenuView>();
  21. //指定VieModel
  22. //containerRegistry.RegisterForNavigation<ContentView, ContentViewModel>();
  23. //containerRegistry.RegisterForNavigation<MenuView, MenuViewModel>();
  24. }
  25. }
  26. }

2.使用导航

  1. using HT.PrismApp.Views;
  2. using Prism.Commands;
  3. using Prism.Events;
  4. using Prism.Mvvm;
  5. using Prism.Regions;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using System.Windows;
  12. namespace HT.PrismApp.ViewModels
  13. {
  14. public class HeaderViewModel : BindableBase
  15. {
  16. private IRegionManager _regionManager;
  17. public HeaderViewModel(IRegionManager regionManager)
  18. {
  19. _regionManager = regionManager;
  20. }
  21. public DelegateCommand NavigationA
  22. {
  23. get
  24. {
  25. return new DelegateCommand(() =>
  26. {
  27. //使用导航
  28. _regionManager.RequestNavigate("ContentRegion", nameof(ContentView));
  29. });
  30. }
  31. }
  32. public DelegateCommand NavigationB
  33. {
  34. get
  35. {
  36. return new DelegateCommand(() =>
  37. {
  38. //使用导航
  39. _regionManager.RequestNavigate("ContentRegion", nameof(MenuView));
  40. });
  41. }
  42. }
  43. }
  44. }

拓展:

  1. public DelegateCommand NavigationA
  2. {
  3. get
  4. {
  5. return new DelegateCommand(() =>
  6. {
  7. //带参数,ViewModel继承INavigationAware
  8. //OnNavigatedTo: 导航完成前, 此处可以传递过来的参数以及是否允许导航等动作的控制。
  9. //IsNavigationTarget: 调用以确定此实例是否可以处理导航请求。否则新建实例
  10. //OnNavigatedFrom: 当导航离开当前页时, 类似打开A, 再打开B时, 该方法被触发。
  11. //还有可以继承IConfirmNavigationRequest
  12. //拦截导航请求
  13. //public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
  14. //{
  15. // bool result = true;
  16. // if (MessageBox.Show("确认导航?", "温馨提示", MessageBoxButton.YesNo) == MessageBoxResult.No)
  17. // result = false;
  18. // //通过回调当前返回的确认结果,决定是否启动该导航
  19. // continuationCallback(result);
  20. //}
  21. var param = new NavigationParameters();
  22. param.Add("Parameter", param);
  23. _regionManager.RequestNavigate("ContentRegion", nameof(ContentView), param);
  24. //类似URL地址传递参数
  25. //_regionManger.RequestNavigate("ContentRegion", $"{nameof(ContentView)}?id=1&Name=xiaoming");
  26. });
  27. }
  28. }

3.Navigation Journal导航日志

  1. using HT.PrismApp.Views;
  2. using Prism.Commands;
  3. using Prism.Events;
  4. using Prism.Mvvm;
  5. using Prism.Regions;
  6. using Prism.Services.Dialogs;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows;
  13. namespace HT.PrismApp.ViewModels
  14. {
  15. public class HeaderViewModel : BindableBase
  16. {
  17. private IRegionManager _regionManager;
  18. private IRegionNavigationJournal _journal;
  19. public HeaderViewModel(IRegionManager regionManager, IRegionNavigationJournal journal)
  20. {
  21. _regionManager = regionManager;
  22. _journal = journal;
  23. }
  24. public DelegateCommand NavigationA
  25. {
  26. get
  27. {
  28. return new DelegateCommand(() =>
  29. {
  30. _regionManager.RequestNavigate("ContentRegion", nameof(ContentView), args =>
  31. {
  32. //***导航日志
  33. _journal = args.Context.NavigationService.Journal;
  34. });
  35. });
  36. }
  37. }
  38. public DelegateCommand NavigationB
  39. {
  40. get
  41. {
  42. return new DelegateCommand(() =>
  43. {
  44. //使用导航
  45. _regionManager.RequestNavigate("ContentRegion", nameof(MenuView), args =>
  46. {
  47. //***导航日志
  48. _journal = args.Context.NavigationService.Journal;
  49. });
  50. });
  51. }
  52. }
  53. public DelegateCommand GoBack
  54. {
  55. get
  56. {
  57. return new DelegateCommand(() =>
  58. {
  59. _journal.GoBack();
  60. });
  61. }
  62. }
  63. public DelegateCommand GoForward
  64. {
  65. get
  66. {
  67. return new DelegateCommand(() =>
  68. {
  69. _journal.GoForward();
  70. });
  71. }
  72. }
  73. }
  74. }

5.Dialog(对话框)

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

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

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

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

  1. using Prism.Commands;
  2. using Prism.Mvvm;
  3. using Prism.Services.Dialogs;
  4. using System;
  5. namespace HT.PrismApp.ViewModels
  6. {
  7. public class MessageDialogViewModel : BindableBase, IDialogAware
  8. {
  9. public string Title => "对话框服务";
  10. public event Action<IDialogResult> RequestClose;
  11. public bool CanCloseDialog()
  12. {
  13. return true;
  14. }
  15. /// <summary>
  16. /// 对话框关闭时
  17. /// </summary>
  18. public void OnDialogClosed()
  19. {
  20. }
  21. /// <summary>
  22. /// 对话框打开时
  23. /// </summary>
  24. /// <param name="parameters"></param>
  25. public void OnDialogOpened(IDialogParameters parameters)
  26. {
  27. }
  28. public DelegateCommand SaveCommand
  29. {
  30. get
  31. {
  32. return new DelegateCommand(() =>
  33. {
  34. RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
  35. });
  36. }
  37. }
  38. public DelegateCommand CancelCommand
  39. {
  40. get
  41. {
  42. return new DelegateCommand(() =>
  43. {
  44. RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
  45. });
  46. }
  47. }
  48. }
  49. }

5.2注册对话框 RegisterDialog

  1. using HT.PrismApp.ViewModels;
  2. using HT.PrismApp.Views;
  3. using Prism.Ioc;
  4. using System.Windows;
  5. namespace HT.PrismApp
  6. {
  7. /// <summary>
  8. /// Interaction logic for App.xaml
  9. /// </summary>
  10. public partial class App
  11. {
  12. protected override Window CreateShell()
  13. {
  14. return Container.Resolve<MainWindow>();
  15. }
  16. protected override void RegisterTypes(IContainerRegistry containerRegistry)
  17. {
  18. containerRegistry.RegisterDialog<MessageDialog, MessageDialogViewModel>();
  19. }
  20. }
  21. }

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

  1. using HT.PrismApp.Views;
  2. using Prism.Commands;
  3. using Prism.Events;
  4. using Prism.Mvvm;
  5. using Prism.Regions;
  6. using Prism.Services.Dialogs;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows;
  13. namespace HT.PrismApp.ViewModels
  14. {
  15. public class HeaderViewModel : BindableBase
  16. {
  17. private IRegionManager _regionManager;
  18. private IRegionNavigationJournal _journal;
  19. private IDialogService _dialogService;
  20. public HeaderViewModel(IRegionManager regionManager, IRegionNavigationJournal journal, IDialogService dialogService)
  21. {
  22. _regionManager = regionManager;
  23. _journal = journal;
  24. _dialogService= dialogService;
  25. }
  26. public DelegateCommand NavigationA
  27. {
  28. get
  29. {
  30. return new DelegateCommand(() =>
  31. {
  32. _regionManager.RequestNavigate("ContentRegion", nameof(ContentView), args =>
  33. {
  34. //***导航日志
  35. _journal = args.Context.NavigationService.Journal;
  36. });
  37. });
  38. }
  39. }
  40. public DelegateCommand NavigationB
  41. {
  42. get
  43. {
  44. return new DelegateCommand(() =>
  45. {
  46. //使用导航
  47. _regionManager.RequestNavigate("ContentRegion", nameof(MenuView), args =>
  48. {
  49. //***导航日志
  50. _journal = args.Context.NavigationService.Journal;
  51. });
  52. });
  53. }
  54. }
  55. public DelegateCommand GoBack
  56. {
  57. get
  58. {
  59. return new DelegateCommand(() =>
  60. {
  61. _journal.GoBack();
  62. });
  63. }
  64. }
  65. public DelegateCommand GoForward
  66. {
  67. get
  68. {
  69. return new DelegateCommand(() =>
  70. {
  71. _journal.GoForward();
  72. });
  73. }
  74. }
  75. public DelegateCommand OpenDialog
  76. {
  77. get
  78. {
  79. return new DelegateCommand(() =>
  80. {
  81. _dialogService.ShowDialog(nameof(MessageDialog));
  82. });
  83. }
  84. }
  85. }
  86. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/869606
推荐阅读
相关标签
  

闽ICP备14008679号