赞
踩
在最常见的开发模式当中, 我们去设计某个页面的时候, 实际上界面元素在设计的时候已经被固定。
举个简单的例子,当我们去设计如下页面, 它包含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));
- }
- }
- }
在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。
众所周知, 如果你了解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.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();
- });
- }
- }
- }
- }
对话框实际上是我们应用程序经常用到的一个功能, 类如: Show、ShowDialog。
可以弹出一个我们指定的窗口, 仅此而已, 那么在Prism当中, Dialog指的是什么?
Prism提供了一组对话服务, 封装了常用的对话框组件的功能, 例如:
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));
- });
- }
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。