我的最终目标是在 C#.NET 中创建一个向用户显示通知的 Windows 10 应用程序。该通知应包含标题、描述、至少一张图像,并且单击时应打开一个网页。如果用户没有点击它,它也应该存储在通知管理器中(或者 Windows 中列出通知的任何地方)。这就是目标。
我尝试了很多不同的方法来做到这一点,但无法让其中任何一个正常工作。
我当前的代码使用Microsoft.Toolkit.Uwp.NotificationsNuGet 包,主要取自以下示例:
https: //learn.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/adaptive-interactive-toasts ?tabs =构建器语法
就目前而言,以下代码效果很好:
using System;
using System.Windows;
using Microsoft.Toolkit.Uwp.Notifications;
namespace PushClient
{
public partial class App : System.Windows.Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
new ToastContentBuilder()
.AddText("My Title")
.AddText("My Description")
.Show();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是它产生的通知...
第一个问题
第一个问题是我无法添加自定义图像,尽管据说可以通过三种不同的方法添加图像。我首先尝试了这个:
new ToastContentBuilder()
.AddText("My Title")
.AddText("My Description")
.AddAppLogoOverride((new Uri("https://picsum.photos/48?image=883")), ToastGenericAppLogoCrop.Circle)
.Show();
Run Code Online (Sandbox Code Playgroud)
这成功地删除了通知左侧的默认图标,并在底部添加了应用程序的名称(因为这个想法是徽标已被删除,因此必须通过其他方法来识别应用程序)。然而,并没有新的形象取代旧的形象。只是空白。
我也尝试过这样做:
new ToastContentBuilder()
.AddText("My Title")
.AddText("My Description")
.AddHeroImage(new Uri("https://picsum.photos/364/180?image=1043"))
.Show();
Run Code Online (Sandbox Code Playgroud)
但据我所知,这与第一个版本相比几乎没有任何改变。
最后我尝试了这个:
new ToastContentBuilder()
.AddText("My Title")
.AddText("My Description")
.AddInlineImage(new Uri("https://picsum.photos/360/202?image=1043"))
.Show();
Run Code Online (Sandbox Code Playgroud)
这似乎在描述下方添加了一些空白,但没有图像。
第二个问题
另一个问题是我无法弄清楚如何通过此过程添加完整的 onclick 操作。我对需要单击的按钮或通知本身的单击操作非常满意。但无论它如何工作,它最终都需要在用户的默认浏览器中打开指定的 URL。
其他尝试
我还玩过其他发送通知的过程,比如这个ShowBalloonTip过程。这似乎根本没有自定义图像的选项,这正是我想要的。但是,我可以从指定的图像列表中选择一个图像,包括我在这段代码中选择的“警告”图标,并且 onclick 操作很容易添加:
using System;
using System.Threading;
using System.Windows;
using System.Windows.Forms;
namespace PushClient
{
public partial class App : System.Windows.Application
{
private NotifyIcon _notifyIcon = new NotifyIcon();
private void Application_Startup(object sender, StartupEventArgs e)
{
try
{
_notifyIcon = new NotifyIcon();
_notifyIcon.Icon = PushClient.Properties.Resources.accountable2you;
_notifyIcon.Visible = true;
_notifyIcon.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip();
Thread t = new Thread(() => LaunchBalloonNotification(_notifyIcon, "My Title", "My Description"));
t.Start();
}
catch (System.Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private static void notifyIcon_BalloonTipClicked(object sender, EventArgs e)
{
Console.WriteLine("Action clicked");
}
private static void LaunchBalloonNotification(NotifyIcon ico, String title, String msg)
{
ico.ShowBalloonTip(
10000,
title,
msg,
ToolTipIcon.Warning
);
ico.BalloonTipClicked += new EventHandler(notifyIcon_BalloonTipClicked);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用ToastNotificationManager,但我得到的结果与我得到的结果相同Microsoft.Toolkit.Uwp.Notifications......除了ToastNotificationManager需要AppID工作,而且我很难弄清楚我应该如何正确地创建这样一个我的小型 Visual Studio 测试应用程序的东西。
不管怎样,如果你能指出正确的方向来帮助我实现我的目标(最好是一个最小的、可重现的例子!),我将不胜感激!
在评论中提供的链接 @Fildor 的帮助下,以及对如何处理本地图像的一些创造性思考,我终于有了一个可行的解决方案。这是链接: https://learn.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast ?tabs=desktop
我最终将我需要的两个图像(这两个图像都将与应用程序一起部署)转换为数据 URI,就像人们可能在 HTML 中使用的那样。然后我把它们保存在本地。Uri然后我在方法中使用 C#对象AddAppLogoOverride。可能有一种更简单的方法,但这是我能想到的最有效的方法。
我的修改和工作(即“工作”,如果您使用上传到 Opinionatedgeek 编码器的真实图像中的真实图像数据)示例代码如下。
using System;
using System.Windows;
using Microsoft.Toolkit.Uwp.Notifications;
using System.IO;
namespace PushClient
{
public partial class App : System.Windows.Application
{
private String imageFilePath = String.Empty;
private void Application_Startup(object sender, StartupEventArgs e)
{
try
{
SaveImageFilesToCommonFolder();
LaunchToastNotification("Hello World!", "This is such a nice world!", "https://presuppositions.org");
}
catch (System.Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private void LaunchToastNotification(string title, string description, string url)
{
// https://learn.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast?tabs=desktop
Uri img = new Uri(imageFilePath);
// Listen to notification activation
ToastNotificationManagerCompat.OnActivated += toastArgs =>
{
// Obtain the arguments from the notification
ToastArguments args = ToastArguments.Parse(toastArgs.Argument);
// /sf/ask/320618441/
System.Diagnostics.Process.Start(args["url"]);
};
new ToastContentBuilder()
.AddText(title)
.AddText(description)
.AddAppLogoOverride(img)
.AddButton(new ToastButton()
.SetContent("View Report")
.AddArgument("action", "viewReport")
.AddArgument("url", url))
.Show();
}
private string SaveDataUrlToFile(string dataUrl, string savePath)
{
// /sf/ask/1939740351/
var binData = Convert.FromBase64String(dataUrl);
System.IO.File.WriteAllBytes(savePath, binData);
return savePath;
}
private void SaveImageFilesToCommonFolder()
{
// /sf/ask/1939740351/
// Write images to common app data folder
var directory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
// Uploaded PNG to this location to get the Data URI,
// which is really much longer than displayed here:
// https://www.opinionatedgeek.com/codecs/base64encoder
String imageFileData = "iVBORw0KGgoAAAANUgAAAMAAAADRU5ErkJggg==";
imageFilePath = Path.Combine(directory, "myimage.png");
SaveDataUrlToFile(imageFileData, imageFilePath);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22673 次 |
| 最近记录: |