WPF 不带 TargetPlatformVersion 显示 Win10 的 Toast 通知的方法

news/2024/11/16 0:28:18/文章来源:https://www.cnblogs.com/lindexi/p/18333724

本文将告诉大家如何在 WPF 不安装 WindowsAppSDK 包,且不在 TargetFramework 带上 TargetPlatformVersion 而弹出 Win10 的 Toast 通知的方法

本文这里的 TargetPlatformVersion 指的是在 TargetFramework 里面的内容,如下面的代码里的 10.0.17763.0 就是 TargetPlatformVersion 的值

  <PropertyGroup><TargetFramework>net9.0-windows10.0.17763.0</TargetFramework></PropertyGroup>

不带 TargetPlatformVersion 即不在 TargetFramework 里加上 10.0.x 的版本号

默认微软官方推荐使用的是千年不更新的 Microsoft.Toolkit.Uwp.Notifications 库,配合设置了 TargetPlatformVersion 至少为 10.0.17763.0 版本进行 Toast 通知

其默认推荐方法的 csproj 内容大概如下

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>WinExe</OutputType><TargetFramework>net9.0-windows10.0.17763.0</TargetFramework><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings><UseWPF>true</UseWPF></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" /></ItemGroup>
</Project>

此方式需要引用 Microsoft.Toolkit.Uwp.Notifications 且在 TargetFramework 里加上 10.0.17763.0 版本。其使用方法非常简单,如下面代码即可弹出文本

        var builder = new ToastContentBuilder().AddText("林德熙是逗比");builder.Show();

然而以上方法我感觉不够清真。接下来来将告诉大家一个我感觉比较清真的方法

使用 WPF 不安装 WindowsAppSDK 使用 WinRT 功能的方法 这篇博客提到的方法,即可不用指定 TargetPlatformVersion 就可以使用 WinRT 的功能

正好 Toast 就是 WinRT 的功能

具体的做法是先取出 Microsoft.Windows.SDK.NET.dll 和 WinRT.Runtime.dll 两个文件作为引用,我这里放在了我的 C:\lindexi\Library 文件夹里,修改 csproj 引用这两个文件,修改之后的 csproj 文件代码如下

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>WinExe</OutputType><TargetFramework>net9.0-windows</TargetFramework><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings><UseWPF>true</UseWPF></PropertyGroup><ItemGroup><Reference Include="Microsoft.Windows.SDK.NET"><HintPath>C:\lindexi\Library\Microsoft.Windows.SDK.NET.dll</HintPath></Reference><Reference Include="WinRT.Runtime"><HintPath>C:\lindexi\Library\WinRT.Runtime.dll</HintPath></Reference></ItemGroup></Project>

如此可以看到 csproj 不需要加上 TargetPlatformVersion 的引用,也没有 WindowsAppSDK 的引用。看起来清真

完成以上代码之后,我在 MainWindow 的 Loaded 事件尝试弹出通知内容。先根据 https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts?tabs=xml 文档构建出 XML 代码,我这里的例子代码只显示一行文本

 <toast><visual><binding template='ToastText01'><text id="1">显示文本内容</text></binding></visual></toast>

完成构建 XML 代码之后,需要转换为 XmlDocument 对象,代码如下

            var xmlDocument = new XmlDocument();// lang=xmlvar toast = """<toast><visual><binding template='ToastText01'><text id="1">显示文本内容</text></binding></visual></toast>""";xmlDocument.LoadXml(xml: toast);

使用 XML 直接写比较适合简单的业务,可以看到以上的代码十分简单

除了直接编写 XML 之外,还可以使用模版辅助,如下面代码,在 ToastNotificationManager 里面获取模版,然后在模版里面添加内容

xmlDocument = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
XmlNodeList stringElements = xmlDocument.GetElementsByTagName("text");
stringElements[0].AppendChild(xmlDocument.CreateTextNode("显示文本内容"));

以上这两个方式的效果都是差不多的,大家可以选自己喜欢的方式

完成基础配置之后,接下来使用 ToastNotificationManager 将通知弹出,代码如下

            var toastNotification = new ToastNotification(xmlDocument);var toastNotificationManagerForUser = ToastNotificationManager.GetDefault();var toastNotifier = toastNotificationManagerForUser.CreateToastNotifier(applicationId: "应用名");toastNotifier.Show(toastNotification);

以上代码有一个细节是 CreateToastNotifier 需要传入应用名,如果没有传入将炸异常,这是微软设计问题

最后别忘记了在开始调用 WinRT 之前,使用 ComWrappersSupport 进行初始化

            global::WinRT.ComWrappersSupport.InitializeComWrappers();

完成之后的代码如下

public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();Loaded += MainWindow_Loaded;}private void MainWindow_Loaded(object sender, RoutedEventArgs e){if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 15063)){global::WinRT.ComWrappersSupport.InitializeComWrappers();// 以下 XML 的构建,请看// https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts?tabs=xmlvar xmlDocument = new XmlDocument();// lang=xmlvar toast = """<toast><visual><binding template='ToastText01'><text id="1">显示文本内容</text></binding></visual></toast>""";xmlDocument.LoadXml(xml: toast);var toastNotification = new ToastNotification(xmlDocument);var toastNotificationManagerForUser = ToastNotificationManager.GetDefault();var toastNotifier = toastNotificationManagerForUser.CreateToastNotifier(applicationId: "应用名");toastNotifier.Show(toastNotification);}}
}

尝试运行以上代码,就可以看到在窗口加载之后,弹出一条通知消息

本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码。我整个代码仓库比较庞大,使用以下命令行可以进行部分拉取,拉取速度比较快

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin ffad2f4c67a9e53fb9121f5d807191a5a913098d

以上使用的是国内的 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin ffad2f4c67a9e53fb9121f5d807191a5a913098d

获取代码之后,进入 WPFDemo/LenukelbawChejeabecacar/HeregemdibeHeaqereweganilai 文件夹,即可获取到源代码

更多技术博客,请参阅 博客导航

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/774420.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读零信任网络:在不可信网络中构建安全系统05网络代理

网络代理1. 网络代理 1.1. 安全策略在认证和授权环节都充分地利用了多个因子,综合考虑了用户及其使用的设备的信息 1.1.1. 允许员工通过企业发放的工作笔记本电脑提交源代码,但是禁止员工使用手机进行类似操作 1.1.2. 用户必须使用可信终端提交代码,并且这个终端必须属于用户…

Activity创建与跳转

layout目录下新建activity_main2.xml<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.…

Linux工作原理14桌面和打印简介

14桌面和打印简介 本章简要介绍了典型 Linux 桌面系统中的组件。在 Linux 系统的各种软件中,桌面是最狂野、最丰富多彩的领域之一,因为有如此众多的环境和应用程序可供选择,而且大多数发行版都能让你比较容易地试用它们。 与 Linux 系统的其他部分(如存储和网络)不同,创建…

NDT论文翻译

The Normal Distributions Transform: A New Approach to Laser Scan Matching 正态分布变换:激光扫描匹配的新方法 摘要:匹配 2D 范围扫描是许多定位和建图算法的基本组成部分。大多数扫描匹配算法需要找到所使用的特征(即点或线)之间的对应关系。我们提出了范围扫描的替代…

Crypto 杂题选做

ctf stuff?apj 你在干神魔 目录W4terCTF 2024Merciful ZMJ4396d3Google CTF 2023LEAST COMMON GENOMINATORDeadSec CTF 2024Raul RosascorCTF 2024stepsmonkfish / anglerfish W4terCTF 2024 之前朋友给我看的题 Merciful ZMJ4396 找不到原来的 task.py 了,记得大概是这么个题…

我用Awesome-Graphs看论文:解读X-Stream

这次向大家分享发表在SOSP 2013上的另一篇经典图计算框架论文X-Stream,构建了单机上基于外存的Scatter-Gather图处理框架。X-Stream论文:《X-Stream: Edge-centric Graph Processing using Streaming Partitions》前面通过文章《论文图谱当如是:Awesome-Graphs用200篇图系统…

关于new、delete函数的错误处理(std::nothrow)

new、delete函数源码注释如下:无参数 无参数的new、delete函数,如果调用失败,会抛出bad_alloc异常,需要使用try{}catch(){}语句捕获异常从而进行异常处理。 #include <iostream>int main() {try {while (1){int *p = new int[100000000ul];}} catch (std::bad_alloc&…

了解GraphRAG

了解GraphRAG转载:从零实现大模型-GraphRAG,构建LLM中的关系数据库开源地址:https://github.com/microsoft/graphrag 论文:From Local to Global: A Graph RAG Approach to Query-Focused Summarization 博客介绍:https://microsoft.github.io/graphrag/传统RAGLLM预训练和…

Laconic Private Set-Intersection From Pairings (2022)

Laconic Private Set-Intersection From Pairings (2022)[!IMPORTANT] 论文地址:https://eprint.iacr.org/2022/529.pdf 代码地址:https://github.com/relic-toolkit/relic/tree/main/demo/psi-client-server 代码运行参考:RELIC 库学习Laconic 算法介绍 Laconic 适用于算力…

供热从清洁走向智慧

清洁供热是一种以末端需求为核心的拉动式供热方式,可以通过全面实施智慧供热,实现热电协同、多能互补,以打通供热最后一公里,使供热更加智慧化、高效化、绿色化。“清洁供热是一种以末端需求为核心的拉动式供热方式,可以通过全面实施智慧供热,实现热电协同、多能互补,以…

netty核心流程(一):服务端如何建立连接

为了接收连接请求, Netty 服务端应该做些什么事情? 根据Java NIO 的知识,服务端在准备接收客户端连接之前做了下面几个工作,我们可以带着问题往下看。服务端对连接请求是如何初始化的? 如何把用户定义的处理逻辑 childHandler 加入到 Netty 的处理流程里? 如何在 Socket …