原文:从PRISM开始学WPF(九)交互Interaction?

0x07交互

这是这个系列的最后一篇了,主要介绍了Prism中为我们提供几种弹窗交互的方式。

Notification通知式

Prism通过InteractionRequest 来实现弹窗交互,它是一个泛型接口,不同的类型对应不同类型的弹窗方式。
在使用InteractionRequest的时候需要在,xaml中需要注册一个Trigger:

    <i:Interaction.Triggers><prism:InteractionRequestTrigger SourceObject="{Binding NotificationRequest}"><prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True" /></prism:InteractionRequestTrigger></i:Interaction.Triggers>

Interaction

这里用到了Interaction,他是i命名空间里的东西,那么i是什么呢?
interactivity这个是微软内置的类库,他提供了一组用户交互的类,比如我们这里用到的EventTrigger可以用来执行事件触发的操作。
在使用的时候,先引入xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
或者xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity",然后在xaml中使用他:

<i:Interaction.Triggers><i:EventTrigger></i:EventTrigger>
</i:Interaction.Triggers>

而 prism:PopupWindowAction 的 IsModal=True意味着弹框不被关闭的时候,父窗体无法使用。我刚搜索了一下,这个词的翻译竟然“模态”。

模态对话框(Modal Dialogue Box,又叫做模式对话框),是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。 如单击【确定】或【取消】按钮等将该对话框关闭。

好,接着,我们在code-behind中声明,使用INotification类型:

        public InteractionRequest<INotification> NotificationRequest { get; set; }

在command的回调函数中就可以使用NotificationRequest:

            NotificationRequest.Raise(new Notification { Content = "Notification Message", Title = "Notification" }, r => Title = "Notified");

最后通过ConfirmationRequest.Raise()方法来实现调用弹窗,这里将Title修改为“Notified”。

Confirmation 确认式

跟Notification的使用方法一样,先注册Trigger:

        <prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest}"><prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True" /></prism:InteractionRequestTrigger>

然后在使用InteractionRequest的时候使用IConfirmation类型:

        public InteractionRequest<IConfirmation> ConfirmationRequest { get; set; }

callback:

            ConfirmationRequest.Raise(new Confirmation {Title = "Confirmation",Content = "Confirmation Message" }, r => Title = r.Confirmed ? "Confirmed" : "Not Confirmed");

原本一直好奇为什么r能获取confirmationconfirmed属性,后来才发现,自学这个东西,急于求成是不行的。
看下prism的 ConfirmationRequest.Raise()方法:

        /// <summary>/// Fires the Raised event./// </summary>/// <param name="context">The context for the interaction request.</param>/// <param name="callback">The callback to execute when the interaction is completed.</param>[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]public void Raise(T context, Action<T> callback){var handler = this.Raised;if (handler != null){handler(this, new InteractionRequestedEventArgs(context, () => { if(callback != null) callback(context); } ));}}

CustomPopupRequest 客制化

上面的通知和提示窗体,都是内置的,很多时候,我们需要自制一些弹窗来满足更复杂的使用场景,比如我们通过弹窗来传递一些信息,贴心的Prism同样为我们准备了一个接口IInteractionRequestAware:

        //// Summary://     The Prism.Interactivity.InteractionRequest.INotification passed when the interaction//     request was raised.INotification Notification { get; set; }//// Summary://     An System.Action that can be invoked to finish the interaction.Action FinishInteraction { get; set; }

蛤蛤,Notification正是我们需要的东西,再看看他是什么鬼

        //// Summary://     Gets or sets the title to use for the notification.string Title { get; set; }//// Summary://     Gets or sets the content of the notification.object Content { get; set; }

原来这个被用来传递的东西,也有标准,需要一个名字和一个内容,内容是object,也就是,我们可以用他来装下任何东西。

FinishInteractioninvoke来关闭交互界面,这个很简单,具体他怎么关闭的暂时不看了。接下来,我们大概有一个思路了:
首先,先定义好我们需要数据载体类实现INotification,再设计一个usercontrole,他的vm实现IInteractionRequestAware接口,然后在NotificationRequest.Raise的时候使用usercontrole,美滋滋!!!
我们来通过客制化弹窗,实现从一个字符串列表中选择一个字符串,返回给父窗体:

先设计Notification,他并没有直接实现INotification,而是实现了IConfirmation,IConfirmationINotification的基础上,添加了一个Confirmed属性,来获取弹窗返回状态,是布尔型的(布尔型只有两种状态,很多时候,我需要有战斗机一般多的按钮的时候,他就不够用了,到时候得重新设计一个枚举类型的),这里,我们就直接实现IConfirmation为什么先是搞了一个接口呢?当然是为了依赖注入啊!依赖注入很难讲,以前我也看了很多大佬的资料,但是没有懂,后来去问大佬,大佬说,你看懂了吗?我说似懂非懂,他说,那就去看代码吧,慢慢的就懂了。):

using Prism.Interactivity.InteractionRequest;namespace UsingPopupWindowAction.Notifications
{public interface ICustomNotification : IConfirmation{string SelectedItem { get; set; }}
}

接着是我们的实现类(一个list(源),一个string(目标))继承 Confirmation实现我们的接口ICustomNotification,继承 Confirmation是因为他继承自Notification,而Notification是实现了INotification的,这样,我们就在我们的类里不用去实现INotification了,其实也可以不用继承·Confirmation·,完全可以自己实现ICustomNotification他所有的接口(话说若干年前我怎么记得接口不可以被继承只能被实现呢?记错了?):

using Prism.Interactivity.InteractionRequest;
using System.Collections.Generic;namespace UsingPopupWindowAction.Notifications
{public class CustomNotification : Confirmation, ICustomNotification{public IList<string> Items { get; private set; }public string SelectedItem { get; set; }public CustomNotification(){this.Items = new List<string>();this.SelectedItem = null;CreateItems();}private void CreateItems(){//add some items}}
}

如果不继承Confirmation,则需要添加部分实现:

public bool Confirmed { get ; set ; }public string Title { get ; set ; }public object Content { get ; set ; }

接下来设计我们的弹窗(一个列表(显示源),两个按钮,一个取消一个提交(获取目标)):

        <TextBlock Margin="10" TextWrapping="Wrap" FontWeight="Bold">Please select an item:</TextBlock><ListBox SelectionMode="Single" Margin="10,0" Height="100" ItemsSource="{Binding Notification.Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"></ListBox><Grid><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition /></Grid.ColumnDefinitions><Button AutomationProperties.AutomationId="ItemsSelectButton" Grid.Column="0" Margin="10" Command="{Binding SelectItemCommand}">Select Item</Button><Button AutomationProperties.AutomationId="ItemsCancelButton" Grid.Column="1" Margin="10" Command="{Binding CancelCommand}">Cancel</Button></Grid>

弹窗的ViewModel,实现IInteractionRequestAware接口,这里设置了一个_notification来接收我们用来传递的那个类,这很像MVC里的Model,他只是个数据的载体,在每一个命令最后都需要关闭窗体,并且之前对confirmed和我们的SelectedItem进行赋值:
依旧省去了大部分代码,只看与我们有关的部分

    public class ItemSelectionViewModel : BindableBase, IInteractionRequestAware{public string SelectedItem { get; set; }private void CancelInteraction(){_notification.SelectedItem = null;_notification.Confirmed = false;FinishInteraction?.Invoke();}private void AcceptSelectedItem(){_notification.SelectedItem = SelectedItem;_notification.Confirmed = true;FinishInteraction?.Invoke();}public Action FinishInteraction { get; set; }private ICustomNotification _notification;public INotification Notification{get { return _notification; }set { SetProperty(ref _notification, (ICustomNotification)value); }}}
}

最后就是在Shell里调用这个客制化弹窗啦,跟之前的就一毛一样了,将INotification或者IConfirmation替换成我们的ICustomNotification,然后在new的时候使用CustomNotification,代码看上去应该是这个样子的:
xaml:

<prism:InteractionRequestTrigger SourceObject="{Binding CustomNotificationRequest}"><prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"><prism:PopupWindowAction.WindowContent><views:ItemSelectionView /></prism:PopupWindowAction.WindowContent></prism:PopupWindowAction></prism:InteractionRequestTrigger>

viewmodel:

   public InteractionRequest<ICustomNotification> CustomNotificationRequest { get; set; }public DelegateCommand CustomNotificationCommand { get; set; }public MainWindowViewModel(){CustomNotificationRequest = new InteractionRequest<ICustomNotification>();CustomNotificationCommand = new DelegateCommand(RaiseCustomInteraction);}private void RaiseCustomInteraction(){CustomNotificationRequest.Raise(new CustomNotification { Title = "Custom Notification" }, r =>{if (r.Confirmed && r.SelectedItem != null)Title = $"User selected: { r.SelectedItem}";elseTitle = "User cancelled or didn't select an item";});}

最后一篇了!我会持续修正之前文章里理解偏颇的地方。谢谢大家!

从PRISM开始学WPF(九)交互Interaction?相关推荐

  1. 从PRISM开始学WPF(四)Prism-Module?

    原文:从PRISM开始学WPF(四)Prism-Module? 从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Regio ...

  2. 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator?

    从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? 原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? 从PRISM开始学 ...

  3. 一起学WPF系列(2):第一个WPF应用程序

    概述 Windows Presentation Foundation (WPF) 是下一代显示系统,用于生成能带给用户震撼视觉体验的 Windows 客户端应用程序.使用 WPF,您可以创建广泛的独立 ...

  4. graphpad prism横坐标怎么设置不显示数值_Graphpad Prism能不能画九象限图?

    原标题:Graphpad Prism能不能画九象限图? 我在上周一文介绍了如何使用Prism绘制火山图,在发现了可以将点的颜色与分组数据建立映射之后,我想Prism肯定也能画九象限图.于是,这里我再尝 ...

  5. 记忆力很差怎么学计算机,九个方法增强记忆力 学生记忆力很差怎么办

    增强记忆力的方法有学习一种新语言.左右水平转动眼睛30秒.冥想的同时深呼.适当运用左手.睡个好觉多呼吸新鲜空气等. 中学生提高记忆力方法 我们可以从以下15个要点中着手,结合自身的实际情况加以改进和完 ...

  6. WPF 九 ( loaded 事件和 Initialized 事件区别以及事件执行顺序总结)

    在 WPF 中, 控件有 Loaded 和 Initialized 两种事件. 初始化和加载控件几乎同时发生, 因此这两个事件也几乎同时触发. 但是他们之间有微妙且重要的区别..具体区别如下 概念介绍 ...

  7. MBSE建模学习之五:交互(Interaction)和序列图

    版本更新信息 智睿思维基于模型的系统工程软件(MBSES)1.5版正式发布.新版的主要改进如下: (1)打开项目.打开图更快.图形工具栏增加过滤功能,查找节点的元素模板更方便. (2)支持项目模板.选 ...

  8. 教妹学Java(九):一文搞懂Java中的基本数据类型

    大家好,我是沉默王二,一个和黄家驹一样身高,和刘德华一样颜值的程序员.本篇文章通过我和三妹对话的形式来谈一谈"Java 中的数据类型". 教妹学 Java,没见过这么有趣的标题吧? ...

  9. 今年十个学软件测试九个在待业,看我如何破局成功且年薪50w,怎么才能做到?

    你知道什么叫 度日如年 吗?就是在家待业的每一天. 你知道什么叫心焦如焚吗?就是投出100份简历却等不来一个回应. 当前就业环境,裁员.失业消息满天飞,好像能有一份工作就不错了,更别说高薪.其实这只是 ...

最新文章

  1. 结对第2次作业——WordCount进阶需求
  2. YYDS 的 IDEA插件,没装上的安排起来!
  3. 替换字符串中指定的字符--随手源码
  4. 寻找一个字符串中的最长不重复子串的长度
  5. 递归 反转字符串_使用递归反转字符串
  6. dataframe修改数据_数据处理进阶pandas入门(一)
  7. USB HID学习:MFC检测USB拔插事件
  8. UI素材干货模板|网页“按钮”组件,教你要如何设计!
  9. python如何屏幕截图_Python编写屏幕截图程序方法
  10. Podfile使用说明
  11. 走迷宫 6 6 c语言,游戏迷宫的实现
  12. 千万流量大型分布式系统架构设计实战(干货)
  13. [翻译]:Cinemachine 官方文档(0)
  14. 新手入门 | Pr剪辑教程
  15. c语言二进制转换方式,c语言二进制怎么转换十进制
  16. wp8小程序第七次更新成功
  17. 我们一起写opengl程序
  18. VMware虚拟机win10系统桥接模式连不上网
  19. 结构化数据和非结构化数据有何区别?
  20. Linux Cgroup cpu子系统实验

热门文章

  1. 养鸡农场小程序游戏京东拼多多优惠券附近商家流量主购物源码-修复登录接口
  2. java统计文件字符数量_Java统计文件注释个数和注释字符数
  3. ds18b20温度转换指令_STM32接口DS18S20温度传感器
  4. 面相终端的计算机网络的阶段特征,计算机网络习题汇编
  5. html怎么控制进度条,HTML如何实现进度条?附源码
  6. ironpython2.7.8相当于python3.7吗_IronPython与numpy的Python速度之比较
  7. 超美响应式自适应引导页带音乐播放器源码
  8. 二开的精美UI站长源码分享论坛网站源码 可切换皮肤界面
  9. 改变浏览器视角大小:Viewport Resizer
  10. Moodle: Remove customise this page button from profile?