且听疯吟 如此生活三十年
在 Windows 8 Desktop App 中使用 Toast Notification

最近坐久了就感觉腰酸背痛,想要做个定时提醒,提醒自己定时休息走动一下。
现在的定时提醒软件要么太复杂要么太难看,本来想要使用系统自带的定时任务,但是 Windows 8 中废弃了计划任务中的弹出消息功能。

想到 Windows 8 中新增了 Toast Notification,能不能利用这个方式来提醒?但是没见过 Desktop app 使用这个功能,一直以为是 Windows Store App 专用的 API。
在翻 MSDN 的时候发现原来 Metro Toast Notification 适用范围也包括 Desktop app。然后折腾了一下,居然成功了:)

demo

在 Desktop app 中使用 Windows 8/Windows RT API

Toast 位于 Windows.UI.Notifications 命名空间中,但是默认情况下没法引用该命名空间,因为其中一些 API 在 Desktop 环境下是有限制的。幸运的是 Toast Notification 不属于其中。可以从 MSDN 上找到这些 API 的详细信息,其中就包括了适用范围 。

  • 建立一个 Console Application,为了引用 Windows.UI.Notifications,需要编辑项目文件 .csproj。在第一个 PropertyGroup 节点中添加
<TargetPlatformVersion>8.0</TargetPlatformVersion>
  • 重新 Load 项目,添加引用。可以看到引用管理器左边添加了新的一列 Windows,添加 Windows.Data.Xml.Dom Windows.UI.Notifications
    Windows.Foundation 的引用。
  • 添加对 System.RuntimeSystem.Runtime.InteropService.WindowsRuntime 的引用。

使用 Console app 创建 Toast Notification

接下来需要创建一个 ToastTemplateType 对应的 XmlDocument 对象。
关于不同的 ToastTemplateType ,可以在 MSDN 找到详细的信息。
ToastTemplateType.ToastImageAndText04 为例,这是一个带有 Image 和三行文字的 Toast Template

  • 创建 Template 如下:
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04);

Windows.Data.Xml.Dom.XmlNodeList stringElements = toastXml.GetElementsByTagName("text");
stringElements[0].AppendChild(toastXml.CreateTextNode("Head"));
stringElements[1].AppendChild(toastXml.CreateTextNode("Content1"));
stringElements[2].AppendChild(toastXml.CreateTextNode("Content2"));

String imagePath = "file:///" + Path.GetFullPath("toastImageAndText.png");
Windows.Data.Xml.Dom.XmlNodeList imageElements = toastXml.GetElementsByTagName("image");
imageElements[0].Attributes.GetNamedItem("src").NodeValue = imagePath;
  • 创建 Toast 并添加事件:
ToastNotification toast = new ToastNotification(toastXml);
toast.Activated += ToastActivated;
toast.Dismissed += ToastDismissed;
toast.Failed += ToastFailed;
  • 弹出 Toast:

    在 Desktop app 中使用 Toast 时需要一个 App id,否则会出现 找不到元素 的异常。
string appId = "Microsoft.Samples.DesktopToastsSample";
ToastNotificationManager.CreateToastNotifier(appId).Show(toast);

其他

这里是个简单的示例项目源码 Windows8ToastNotification
考虑用这个写个小玩具,可以获取关注的 Twitter、世界杯比分、天气预报之类的通知,支持 API 自定义,想想还挺好玩的,完成后会更新到 Github。