原文:【wpf】在win10系统上弹出toast和notification

老规矩,先看效果

右下角的notification

操作中心的notification

整体效果

前提条件

1.需要在开始菜单里添加快捷方式。

2.在注册表里注册你实现了INotificationActivationCallBack接口的com组件。

3.一个APP_ID,添加到快捷方式里,ActionCenter会以此来区分不同应用的消息。

缺一不可,不然弹出的notification没法交互。

实现

1.添加相关引用

编辑你项目的csproj文件,添加如下节点

<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>

然后看起来就是这个样子:

接下来打开引用管理器你会发现左边多了一个Windows选项卡,然后添加图示的三个引用:

然后再添加System.Runtime和System.Runtime.InteropServices.WindowsRuntime引用。



这两个引用在:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\Facades\文件夹中,如果你的.net 4.5.2的framework请改为v4.5.2。

2.添加快捷方式

private void InstallShortcut(String shortcutPath, String exePath)
{
IShellLinkW newShortcut = (IShellLinkW)new CShellLink();
newShortcut.SetPath(exePath);
newShortcut.SetWorkingDirectory(Path.GetDirectoryName(exePath));
IPropertyStore newShortcutProperties = (IPropertyStore)newShortcut;
PropVariantHelper varAppId = new PropVariantHelper();
varAppId.SetValue(APP_ID);
newShortcutProperties.SetValue(PROPERTYKEY.AppUserModel_ID, varAppId.Propvariant);
PropVariantHelper varToastId = new PropVariantHelper();
varToastId.VarType = VarEnum.VT_CLSID;
varToastId.SetValue(typeof(NotificationActivator).GUID);
newShortcutProperties.SetValue(PROPERTYKEY.AppUserModel_ToastActivatorCLSID, varToastId.Propvariant);
ShellHelpers.IPersistFile newShortcutSave = (ShellHelpers.IPersistFile)newShortcut;
newShortcutSave.Save(shortcutPath, true);
}

3.注册com组件

private void RegisterComServer(String exePath)
{
string regString = String.Format("SOFTWARE\\Classes\\CLSID\\{{{0}}}\\LocalServer32", typeof(NotificationActivator).GUID);
var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regString);
key.SetValue(null, exePath);
}

这样ActionCenter就可以通过GUID找到你的exe文件。

4.设置通知的内容样式

通知的样式有很多种,图片、文字、按钮、输入框可以组合使用。详情见最下面的参考链接。

这里我贴出下我例子里的布局设置。

private void btncl(object sender, RoutedEventArgs e)
{
ToastContent content = new ToastContent()
{
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText()
{
Text="New Mirrored Folders Created"//标题
},
new AdaptiveText()
{
Text="Drag some files to either Mirror folder to sync\nClick to show the Mirror folder on my..."//内容
}
},
AppLogoOverride = new ToastGenericAppLogo()
{
Source = new System.Uri(System.IO.Path.GetFullPath("123.png")).AbsoluteUri//通知的图标
} }
},
Scenario = ToastScenario.Alarm,//设置通知的声音 //三个button
Actions = new ToastActionsCustom()
{
Buttons =
{
new ToastButton("PC",new QueryString(){
{"action","fileExplorer" },
{"path","c:\\" }
}.ToString())
{
ActivationType=ToastActivationType.Background
},
new ToastButton("Drive",new QueryString(){
{"action","fileExplorer" },
{"path","d:\\" }
}.ToString())
{
ActivationType=ToastActivationType.Background
},
new ToastButtonDismiss("Close")
}
}
};
XmlDocument xml = new XmlDocument();
xml.LoadXml(content.GetContent());
ToastNotification toast = new ToastNotification(xml);
toast.Group = "gg";
//toast.ExpirationTime = DateTime.Now.AddSeconds(20);
//toast.SuppressPopup = true;
ToastNotificationManager.CreateToastNotifier(APP_ID).Show(toast);
}

这里用到了两个库,分别是:



安装完成后,添加引用即可。

1. 里面的QueryString.NET库,是将key-value形式的集合,序列化成一个字符串,因为Notification里的button只接受一个为string类型的arguments。用户点击某个button时,会回调你com组件的Activie方法,在这个方法里拿到arguments,然后进行下一步操作。

2. 如果你不想让右下角弹出通知,只想让通知出现在“操作中心”(通知栏)里,可以设置toast.SuppressPopup=true来进行屏蔽。不过此时是没法播放声音的。

3. 关于如何让通知常驻在”操作中心“这个问题,我发现是不可能的,微软说了”当用户与通知进行交互的时候会自动把这条通知从 操作中心移除“,所以那个toast.ExpirationTime基本没啥作用。(详见下面参考链接)。如果设置了Scenario = ToastScenario.Alarm(Reminder/IncomingCall);用户不点击的话,会一直出现在那里,否则7-8秒后自动消失。

5.程序退出时,清除通知

在退出时调用:

ToastNotificationManager.History.RemoveGroup(....);
//或者
ToastNotificationManager.History.Remove(....)

即可。这样可以删除同属于一个Group的通知,或者删除某个tag=”xxx”的通知,或者整个app_id下的通知。

6.如何做到多个win系统的兼容?

一般你的程序是同时支持win7,win8,win10等的,而win7是无法弹出这种样式的通知的,所以这些引用不能直接添加到主程序里,不然运行时就会报错。

正确的做法就是:将ToastNotification单独做成一个dll,在程序中加入系统版本检测的方法,如果是win10系统,再通过反射的方式,将dll加载到主程序集,然后再弹出通知。


附件:Demo。 如果失效,请留言或来信索取376720513@qq.com

如果你想更灵活的控制弹出的通知,可以参考我这篇博客:【WPF】右下角弹出自定义通知样式(Notification)——简单教程


2018-03-09更新:

NND,今天发现微软更新了一篇又详细的文章,介绍的很好,简直手把手教你。

想看的请移步:Send a local toast notification from desktop C# apps

《参考链接》

1.Quickstart: Handling toast activations from Win32 apps in Windows 10

2.github/desktop-toasts

3.Adaptive and interactive toast notifications

4.Send a local toast notification

【wpf】在win10系统上弹出toast和notification的更多相关文章

  1. 使用Angular CDK实现一个Service弹出Toast组件

    在Angular中,官方团队在开发Material组件库的同时,顺手做了一套Component dev kit,也就是在Angular世界中大名鼎鼎的CDK,这套工具包提供了非常多的前端开发的通用功能 ...

  2. 第一个微信小程序(实现点击一个按钮弹出toast)

    今天根据网上的教程搭建了微信小程序的环境,然后看文档做了一个简单的小应用. 项目的目录是这个样子的: app.js.app.json.app.wxss是全局文件,必不可少的文件.定义在app.wxss ...

  3. Android开发遇到手机无法弹出Toast

    今天遇到了一个很奇怪的问题,一个很简单的程序,就是点击按钮弹出一个Toast,但在手机上运行起来,却没有正常弹出Toast 第一反应就是看看是否调用了show方法,很显然,并不是这个低级问题,为了确定 ...

  4. Android弹出Toast工具类总结

    Android弹出Toast工具类总结,包括系统自带的,也包括自定义的. public class ToastUtil { public ToastUtil() { } public static T ...

  5. 如何在 QWidget 窗口上弹出右键菜单

    Title : QWidget 窗口上弹出右键菜单的两个方法 Solution 1 : 给一个 QWidget 添加 QActions,设置 QWidget 的 contextMenuPolicy 属 ...

  6. 清除ios系统alert弹出框的域名

    清除ios系统alert弹出框的域名 <script> window.alert = function(name) { var iframe = document.createElemen ...

  7. WPF制作子窗体的弹出动画效果

    创建一个WPF应用程序WpfApplication1,新建个窗体DialogWin <Windowx:Class="WpfApplication1.DialogWin" xm ...

  8. python + selenium webdriver 通过python来模拟鼠标、键盘操作,来解决SWFFileUpload调用系统底层弹出框无法定位问题

    Webdriver是基于浏览器操作的,当页面上传文件使用的是flash的控件SWFFileUpload调用的时候,调用的是系统底层的文件选择弹出框 这种情况,Webdriver暂时是不支持除页面外的其 ...

  9. 网页上弹出pop窗口实例,(document).height()与$(window).height()的区别

    #dvbg{background-color:#666666; position:absolute; z-index:99; left:0; top:0; display:none; width:10 ...

随机推荐

  1. ps如何制作gif(窗口->动画)(导出:存储为Web和设备所用格式)

    ps如何制作gif(窗口->动画)(导出:存储为Web和设备所用格式) 一.总结 1.点击窗口,选择动画 2.导出的时候:存储为Web和设备所用格式 二.ps如何制作gif 1.首先我们安装并打 ...

  2. RecyclerView的2种监听方式

    NO.1:在自己定义适配器的ViewHolder里面写监听事件 //RecyclerView适配器 public class RecyclerViewAdapter extends RecyclerV ...

  3. (转自aierong原创技术随笔)sqlserver字符串拆分(split)方法汇总

    sqlserver字符串拆分(split)方法汇总   --方法0:动态SQL法declare @s varchar(100),@sql varchar(1000)set @s='1,2,3,4,5, ...

  4. JAVA中String类的intern()方法的作用

    一般我们变成很少使用到 intern这个方法,今天我就来解释一下这个方法是干什么的,做什么用的 首先请大家看一个例子: public static void main(String[] args) t ...

  5. MySql批量drop table

    原文:MySql批量drop table 今天发现数据库中很多没用的表,想清理掉. 发现mysql好像不支持类似这样的写法:drop table like "%r" 在oracle ...

  6. 使用SecureCRT连接AWS的EC2

    如果使用CentOS等linux系统,直接使用ssh命令即可访问AWS上的Linux-EC2实例. $ ssh -i XXX.pem ec2-user@{IP/hostname} 在Windows系统 ...

  7. BZOJ1415 聪聪与可可 - 期望dp

    传送门 题目大意: 一张无向图上有一只猫和一只老鼠,猫先走,鼠后走.猫每次会向与其相邻的并且距离老鼠最近的点移动(若距离相等去编号较小的),如果移动一步后还没吃到老鼠,还可以再移动一步(算在一个时间内 ...

  8. Codeforces Round #443 (Div. 2) C: Short Program - 位运算

    传送门 题目大意: 输入给出一串位运算,输出一个步数小于等于5的方案,正确即可,不唯一. 题目分析: 英文题的理解真的是各种误差,从头到尾都以为解是唯一的. 根据位运算的性质可以知道: 一连串的位运算 ...

  9. callback回调函数理解 相当于this指针

    1.callback函数在微软的官方手册中是这样定义callback函数的:“callback函数是由应用程序定义而由操作系统调用的函数”.   凡是由用户设计而却由windows系统调用的函数,统称 ...

  10. Docker + .NET Core(一)

    原文:Docker + .NET Core(一) 前言: 环境:centos7.5 64 位 正文: 拉取 microsoft/dotnet, 安装完毕后执行 docker images 可以看到本地 ...