本文参考Prism官方示例

命令使用

Prism提供了两种命令:DelegateCommand和CompositeCommand。

DelegateCommand

DelegateCommand封装了两个委托:Execute和CanExecute,使用如下:

// view
<Button Command="{Binding ExecuteDelegateCommand}" Content="DelegateCommand"/> // viewmodel
public DelegateCommand ExecuteDelegateCommand { get; private set; } public MainWindowViewModel()
{
ExecuteDelegateCommand = new DelegateCommand(Execute, CanExecute);
} private void Execute()
{
UpdateText = $"Updated: {DateTime.Now}";
} private bool CanExecute()
{
return IsEnabled;
}
CompositeCommand

CompositeCommand为复合命令,由多个子命令构成。当调用CompositeCommand时,将依次调用每个子命令。默认情况下,当所有子命令CanExecute均返回true时才会执行CompositeCommand。使用方法如下:

// Project.Core中定义接口及实现
public interface IApplicationCommands
{
CompositeCommand SaveCommand { get; }
} public class ApplicationCommands : IApplicationCommands
{
private CompositeCommand _saveCommand = new CompositeCommand();
public CompositeCommand SaveCommand
{
get { return _saveCommand; }
}
} // App.xaml.cs中注册单例对象
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<
IApplicationCommands, ApplicationCommands>();
} // viewmodel中添加子命令
public TabViewModel(IApplicationCommands applicationCommands)
{
_applicationCommands = applicationCommands; UpdateCommand = new DelegateCommand(Update).ObservesCanExecute(
() => CanUpdate); _applicationCommands.SaveCommand.RegisterCommand(UpdateCommand);
} // view中执行命令(需在对应的viewmodel的构造函数中传入IApplicationCommands实例)
<Button Content="Save" Command="{Binding ApplicationCommands.SaveCommand}"/>

EventAggregator

EventAggregator是一种事件机制,解决了松耦合模块间的通信问题。使用方法如下:

// Project.core中声明事件类型
public class MessageSentEvent : PubSubEvent<string>
{
} // viewmodel中发布事件
IEventAggregator _ea;
public MessageViewModel(IEventAggregator ea)
{
_ea = ea;
// 发布事件的命令
SendMessageCommand = new DelegateCommand(SendMessage);
} private void SendMessage()
{
_ea.GetEvent<MessageSentEvent>().Publish(Message);
} // viewmodel中订阅事件
IEventAggregator _ea;
public MessageListViewModel(IEventAggregator ea)
{
_ea = ea;
_ea.GetEvent<MessageSentEvent>().Subscribe(MessageReceived);
// 如下方式可以过滤事件,可通过第二个参数指定处理线程
// _ea.GetEvent<MessageSentEvent>().Subscribe(MessageReceived,
ThreadOption.PublisherThread, false,
(filter) => filter.Contains("Brian"));
} private void MessageReceived(string message)
{
// hava a message
}

RegionNavigation

区别于View Discovery和View Injection,RegionNavigation可通过region名称与要导航的视图名称实现更通用的视图导航功能,使用如下:

// 模块类中注册导航视图
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ViewA>();
} // xaml导航命令
<Button Command="{Binding NavigateCommand}" CommandParameter="ViewA" >Navigate to View A</Button> // viewmodel实现导航
public DelegateCommand<string> NavigateCommand { get; private set; } public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
} private void Navigate(string navigatePath)
{
if (navigatePath != null)
_regionManager.RequestNavigate("ContentRegion",
navigatePath, NavigationCompleted);
} // 可指定导航完成回调
private void NavigationCompleted(NavigationResult result)
{
// ...
}
INavigationAware接口

INavigationAware接口包含三个方法:OnNavigatedFrom、OnNavigatedTo、IsNavigationTarge。当ViewAViewModel及ViewBViewModel均实现了INavigationAware接口,ViewA导航到ViewB时,先调用ViewA的OnNavigatedFrom方法,然后调用ViewB的IsNavigationTarge,当其返回true时,调用OnNavigatedTo方法,若IsNavigationTarge返回false,创建新ViewB。示例如下:

public class ViewAViewModel : BindableBase, INavigationAware
{
public void OnNavigatedTo(NavigationContext navigationContext)
{
// ...
} public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
} public void OnNavigatedFrom(NavigationContext navigationContext)
{
// ...
}
}
IConfirmNavigationRequest接口

IConfirmNavigationRequest接口继承了INavigationAware接口,并添加了ConfirmNavigationRequest方法。若ViewAViewModel实现了IConfirmNavigationRequest接口,当ViewA导航到ViewB时,先调用ConfirmNavigationRequest方法,若continuationCallback()参数为true,将继续执行导航,执行OnNavigatedFrom方法;若continuationCallback()参数为false,停止导航。示例如下:

public class ViewAViewModel : BindableBase, IConfirmNavigationRequest
{
public void ConfirmNavigationRequest(NavigationContext navigationContext,
Action<bool> continuationCallback)
{
bool result = true; if (MessageBox.Show("Do you to navigate?", "Navigate?",
MessageBoxButton.YesNo) == MessageBoxResult.No)
result = false; continuationCallback(result);
} public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
} public void OnNavigatedFrom(NavigationContext navigationContext)
{
} public void OnNavigatedTo(NavigationContext navigationContext)
{
}
}
IRegionMemberLifetime接口

IRegionMemberLifetime接口只包含一个KeepAlive只读属性。其默认值为true,若其为false,则当该region导航到其它视图时,实现了该接口的当前视图将从IRegion.Views集合中移除并回收。若为true,即使导航到其它视图,该视图依然存在于IRegion.Views集合。示例如下:

public class ViewAViewModel : BindableBase, IRegionMemberLifetime
{
public bool KeepAlive
{
get
{
return false;
}
}
}
参数传递

可使用NavigationParameters实现导航时的参数传递,使用方法如下:

// 导航命令
private void PersonSelected(Person person)
{
var parameters = new NavigationParameters();
parameters.Add("person", person); if (person != null)
_regionManager.RequestNavigate("PersonDetailsRegion",
"PersonDetail", parameters);
} // 参数处理
public void OnNavigatedTo(NavigationContext navigationContext)
{
var person = navigationContext.Parameters["person"] as Person;
// ...
} public bool IsNavigationTarget(NavigationContext navigationContext)
{
var person = navigationContext.Parameters["person"] as Person;
// ...
}
Navigation Journal

Navigation Journal可以记录导航的过程,其通过IRegionNavigationJournal接口实现。通过Navigation Journal,可以实现向前/向后导航。示例如下:

// GoForward
public class PersonListViewModel : BindableBase, INavigationAware
{
IRegionNavigationJournal _journal;
public DelegateCommand GoForwardCommand { get; set; } public PersonListViewModel(IRegionManager regionManager)
{
...
GoForwardCommand = new DelegateCommand(GoForward, CanGoForward);
} // IRegionNavigationJournal.GoBack到行至此
public void OnNavigatedTo(NavigationContext navigationContext)
{
_journal = navigationContext.NavigationService.Journal;
GoForwardCommand.RaiseCanExecuteChanged();
} private void GoForward()
{
_journal.GoForward();
} private bool CanGoForward()
{
return _journal != null && _journal.CanGoForward;
}
} // GoBack
public class PersonDetailViewModel : BindableBase, INavigationAware
{
IRegionNavigationJournal _journal;
public DelegateCommand GoBackCommand { get; set; } public PersonDetailViewModel()
{
GoBackCommand = new DelegateCommand(GoBack);
} public void OnNavigatedTo(NavigationContext navigationContext)
{
_journal = navigationContext.NavigationService.Journal;
} private void GoBack()
{
_journal.GoBack();
}
}

InvokeCommandAction

Prism提供了InvokeCommandAction以使ViewModel处理View的事件,示例如下:

// view xaml
<ListBox ItemsSource="{Binding Items}" SelectionMode="Single">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<prism:InvokeCommandAction Command="{Binding SelectedCommand}"
TriggerParameterPath="AddedItems" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox> // viewmodel
public DelegateCommand<object[]> SelectedCommand { get; private set; } public MainWindowViewModel()
{
...
SelectedCommand = new DelegateCommand<object[]>(OnItemSelected);
} private void OnItemSelected(object[] selectedItems)
{
if (selectedItems != null && selectedItems.Count() > 0)
SelectedItemText = selectedItems.FirstOrDefault().ToString();
}

Prism.WPF -- Prism框架使用(下)的更多相关文章

  1. Prism.WPF -- Prism框架使用(上)

    本文参考Prism官方示例 创建Prism项目 将App.xaml中的WPF标准Application替换为PrismApplication,移除StartupUri属性: 将App.xaml.cs中 ...

  2. .NET Core 3 WPF MVVM框架 Prism系列之命令

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的命令的用法 一.创建DelegateCommand命令 我们在上一篇.NET Core 3 WPF MVVM框架 Prism系列之 ...

  3. .NET Core 3 WPF MVVM框架 Prism系列之模块化

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的应用程序的模块化 前言  我们都知道,为了构成一个低耦合,高内聚的应用程序,我们会分层,拿一个WPF程序来说,我们通过MVVM模式 ...

  4. .NET Core 3 WPF MVVM框架 Prism系列之事件聚合器

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 一.事件聚合器  在上一篇 .NET Core 3 WPF MVVM框架 Prism系列之模块化 ...

  5. .NET Core 3 WPF MVVM框架 Prism系列之导航系统

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism基于区域Region的导航系统 在讲解Prism导航系统之前,我们先来看看一个例子,我在之前的demo项目创建一个登录界面: 我们看 ...

  6. .NET Core 3 WPF MVVM框架 Prism系列之对话框服务

     本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的对话框服务,这也是prism系列的最后一篇完结文章,下面是Prism系列文章的索引: .NET Core 3 WPF MVVM框 ...

  7. [Windows] Prism 8.0 入门(下):Prism.Wpf 和 Prism.Unity

    1. Prism.Wpf 和 Prism.Unity 这篇是 Prism 8.0 入门的第二篇文章,上一篇介绍了 Prism.Core,这篇文章主要介绍 Prism.Wpf 和 Prism.Unity ...

  8. .NET Core 3 WPF MVVM框架 Prism系列文章索引

    .NET Core 3 WPF MVVM框架 Prism系列之数据绑定 .NET Core 3 WPF MVVM框架 Prism系列之命令 .NET Core 3 WPF MVVM框架 Prism系列 ...

  9. Prism(WPF) 拐着尝试入门

    原文:Prism(WPF) 拐着尝试入门 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/s261676224/article/details/852 ...

随机推荐

  1. UESTC 360(1425) another LCIS

    这道题是CD老OJ上面的一道题,现在在新OJ上的题号是360,开始在VJ上做的提交一直RE(囧).后来才知道OJ移位了. 这道题是一个简单的成段更新+区间合并的线段树的题,1A还让我小激动了一下 这道 ...

  2. Codeforces Round #613 (Div. 2) B. Just Eat It!(前缀和)

    题意: 一个长为n的序列,是否存在与原序列不同的连续子序列,其元素之和大于等于原序列. 思路: 从前.后分别累加,若出现非正和,除此累加序列外的子序列元素之和一定大于等于原序列. #include & ...

  3. Codeforces Round #649 (Div. 2) B. Most socially-distanced subsequence

    题目链接:https://codeforces.com/contest/1364/problem/B 题意 给出大小为 $n$ 的一个排列 $p$,找出子序列 $s$,使得 $|s_1-s_2|+|s ...

  4. Educational Codeforces Round 9 C. The Smallest String Concatenation(字符串排序)

    You're given a list of n strings a1, a2, ..., an. You'd like to concatenate them together in some or ...

  5. net core 踩坑记录

    静态文件要放到wwwroot目录中才能访问 linux服务器部署运行报错 System.Net.Http.HttpRequestException: The SSL connection could ...

  6. Pdf和Office相关归集

    Spire 支持Pdf.Office等的诸多操作,使用方便,需收费,免费版本仅支持10页以内的操作,在 这里 可以下载库. 优点 测试过打印效果佳,操作简便. 缺点 PDF打印慢,免费版本仅支持10页 ...

  7. WPF 主动触发依赖属性的 PropertyChanged

    需求背景 需要显示 ViewModel 中的 Message/DpMessage,显示内容根据其某些属性来确定.代码结构抽象如下: // Model public class Message : IN ...

  8. OpenStack Train版-10.安装neutron网络服务(网络节点:可选)

    可选:安装neutron网络服务节点(neutron01网络节点192.168.0.30)网络配置按照官网文档的租户自助网络 配置系统参数 echo 'net.ipv4.ip_forward = 1' ...

  9. LOJ6285 数列分块入门9(分块 区间众数)题解

    题意:给出区间内的最小众数 思路:分块,离散化每个数,开vector记录每个数p出现的位置,这样就能二分出L,R以内p的个数了.众数有一个性质,用mode(a)表示集合a的众数,那么mode(a∪b) ...

  10. LOJ6283 数列分块入门 7 (分块 区间加/乘)题解

    题意:区间加,区间乘,单点询问 思路:假设一个点为a,那么他可以表示为m * a + sum,所以区间加就变为m * a + sum + sum2,区间乘变为m * m2 * a + sum * m2 ...