Windows 8 提供三大通知機制:Toast (彈出通知)、Tile (磚動態更新)、Badge (徽章數字/圖示)。本文從基礎 API 入手,示範手動構造 XML 與使用輔助類庫兩種方式,並涵蓋通知事件處理、清除通知、Badge 徽章更新與輪詢機制。
<Page x:Class="XamlDemo.Notification.Toast.Demo" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Notification.Toast" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel Margin="120 0 0 0"> <TextBox Name="lblMsg" Height="100" TextWrapping="Wrap" AcceptsReturn="True" FontSize="14.667" Margin="0 0 10 0" /> <Button Name="btnShortToast" Content="Short Toast" Click="btnShortToast_Click_1" Margin="0 10 0 0" /> <Button Name="btnLongToast" Content="Long Toast" Click="btnLongToast_Click_1" Margin="0 10 0 0" /> <TextBlock Name="lblStatus" FontSize="14.667" Margin="0 10 0 0" /> </StackPanel> </Page>
using NotificationsExtensions.ToastContent;
using System;
using Windows.Data.Xml.Dom;
using Windows.UI.Core;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Notification.Toast
{
public sealed partial class Demo : Page
{
public Demo()
{
this.InitializeComponent();
}
private void btnShortToast_Click_1(object sender, RoutedEventArgs e)
{
IToastText01 templateContent = ToastContentFactory.CreateToastText01();
templateContent.TextBodyWrap.Text = "我是通知正文,可換行,最多三行。我是通知正文,可換行,最多三行。我是通知正文,可換行,最多三行。";
templateContent.Duration = ToastDuration.Short;
IToastNotificationContent toastContent = templateContent;
ToastNotification toast = toastContent.CreateNotification();
toast.Activated += toast_Activated;
toast.Failed += toast_Failed;
toast.Dismissed += toast_Dismissed;
ToastNotifier toastNotifier = ToastNotificationManager.CreateToastNotifier();
toastNotifier.Show(toast);
lblStatus.Text += "NotificationSetting: " + toastNotifier.Setting.ToString();
lblStatus.Text += Environment.NewLine;
lblMsg.Text = toastContent.GetContent();
}
private void btnLongToast_Click_1(object sender, RoutedEventArgs e)
{
var toastXmlString = "<toast duration='long'>" +
"<visual version='1'>" +
"<binding template='ToastText01'>" +
"<text id='1'>我是通知正文,可換行,最多三行。我是通知正文,可換行,最多三行。我是通知正文,可換行,最多三行。</text>" +
"</binding>" +
"</visual>" +
"<audio silent='true'/>" +
"</toast>";
XmlDocument toastDOM = new XmlDocument();
toastDOM.LoadXml(toastXmlString);
ToastNotification toast = new ToastNotification(toastDOM);
toast.Activated += toast_Activated;
toast.Failed += toast_Failed;
toast.Dismissed += toast_Dismissed;
ToastNotifier toastNotifier = ToastNotificationManager.CreateToastNotifier();
toastNotifier.Show(toast);
lblStatus.Text += "NotificationSetting: " + toastNotifier.Setting.ToString();
lblStatus.Text += Environment.NewLine;
lblMsg.Text = toastXmlString;
}
async void toast_Dismissed(ToastNotification sender, ToastDismissedEventArgs args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
lblStatus.Text += "Toast.Dismissed: " + args.Reason.ToString();
lblStatus.Text += Environment.NewLine;
});
}
async void toast_Failed(ToastNotification sender, ToastFailedEventArgs args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
lblStatus.Text += "Toast.Failed: " + args.ErrorCode.ToString();
lblStatus.Text += Environment.NewLine;
});
}
async void toast_Activated(ToastNotification sender, object args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
lblStatus.Text += "Toast.Activated: " + sender.Content.GetXml();
lblStatus.Text += Environment.NewLine;
});
}
}
}
<Page x:Class="XamlDemo.Notification.Tile.Demo" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Notification.Tile" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <TextBox Name="lblMsg" Height="100" TextWrapping="Wrap" AcceptsReturn="True" FontSize="14.667" Margin="0 0 10 0" /> <Button Name="btnXmlTile" Content="通過手工方式構造 xml 模板,以更新 Tile" Click="btnXmlTile_Click_1" Margin="0 10 0 0" /> <Button Name="btnTemplateTile" Content="通過模板幫助類更新 Tile" Click="btnTemplateTile_Click_1" Margin="0 10 0 0" /> <Button Name="btnClearTile" Content="清除 Tile" Click="btnClearTile_Click_1" Margin="0 10 0 0" /> <TextBlock Name="lblStatus" FontSize="14.667" Margin="0 10 0 0" /> </StackPanel> </Grid> </Page>
using NotificationsExtensions.TileContent;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace XamlDemo.Notification.Tile
{
public sealed partial class Demo : Page
{
public Demo()
{
this.InitializeComponent();
}
private void btnXmlTile_Click_1(object sender, RoutedEventArgs e)
{
string tileXmlString = "<tile>" +
"<visual>" +
"<binding template='TileWideText03'>" +
"<text id='1'>hi webabcd</text>" +
"</binding>" +
"<binding template='TileSquareText04'>" +
"<text id='1'>hi webabcd</text>" +
"</binding>" +
"</visual>" +
"</tile>";
XmlDocument tileDOM = new Windows.Data.Xml.Dom.XmlDocument();
tileDOM.LoadXml(tileXmlString);
TileNotification tile = new TileNotification(tileDOM);
TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
tileUpdater.Update(tile);
lblMsg.Text = tileDOM.GetXml();
lblStatus.Text = "NotificationSetting: " + tileUpdater.Setting.ToString();
}
private void btnTemplateTile_Click_1(object sender, RoutedEventArgs e)
{
ITileSquareImage squareContent = TileContentFactory.CreateTileSquareImage();
squareContent.Image.Src = "https://pic.cnblogs.com/avatar/a14540.jpg?id=24173245";
squareContent.Image.Alt = "altText";
ITileWideImageAndText01 tileContent = TileContentFactory.CreateTileWideImageAndText01();
tileContent.TextCaptionWrap.Text = "hi webabcd";
tileContent.Image.Src = "https://pic.cnblogs.com/avatar/a14540.jpg?id=24173245";
tileContent.Image.Alt = "altText";
tileContent.SquareContent = squareContent;
TileNotification tile = tileContent.CreateNotification();
TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
tileUpdater.Update(tile);
lblMsg.Text = tileContent.GetContent();
}
private void btnClearTile_Click_1(object sender, RoutedEventArgs e)
{
TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
tileUpdater.Clear();
}
}
}
Badge 僅支援兩種模板:BadgeNumber (1-99 數字,超過顯示 99+,0 為移除) 與 BadgeGlyph (12 種預定義圖示:None, Activity, Alert, Available, Away, Busy, NewMessage, Paused, Playing, Unavailable, Error, Attention)。
<Page x:Class="XamlDemo.Notification.Badge.Demo" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Notification.Badge" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <TextBox Name="lblMsg" Height="100" TextWrapping="Wrap" AcceptsReturn="True" FontSize="14.667" Margin="0 0 10 0" /> <Button Name="btnUpdateBadgeWidthNumber" Content="以數字的方式更新 Badge" Click="btnUpdateBadgeWidthNumber_Click_1" Margin="0 10 0 0" /> <Button Name="btnUpdateBadgeWidthIcon" Content="以圖標的方式更新 Badge" Click="btnUpdateBadgeWidthIcon_Click_1" Margin="0 10 0 0" /> </StackPanel> </Grid> </Page>
using NotificationsExtensions.BadgeContent;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace XamlDemo.Notification.Badge
{
public sealed partial class Demo : Page
{
public Demo()
{
this.InitializeComponent();
}
private void btnUpdateBadgeWidthNumber_Click_1(object sender, RoutedEventArgs e)
{
BadgeNumericNotificationContent badgeContent = new BadgeNumericNotificationContent(107);
BadgeNotification badge = badgeContent.CreateNotification();
BadgeUpdater badgeUpdater = BadgeUpdateManager.CreateBadgeUpdaterForApplication();
badgeUpdater.Update(badge);
lblMsg.Text = badgeContent.GetContent();
}
private void btnUpdateBadgeWidthIcon_Click_1(object sender, RoutedEventArgs e)
{
BadgeGlyphNotificationContent badgeContent = new BadgeGlyphNotificationContent(GlyphValue.NewMessage);
BadgeNotification badge = badgeContent.CreateNotification();
BadgeUpdater badgeUpdater = BadgeUpdateManager.CreateBadgeUpdaterForApplication();
badgeUpdater.Update(badge);
lblMsg.Text = badgeContent.GetContent();
}
}
}
透過 BadgeUpdater.StartPeriodicUpdate 定期從伺服器抓取 XML 內容更新徽章,支援相同的週期設定 (30 分鐘至每日)。
<Page x:Class="XamlDemo.Notification.Badge.ScheduledBadge" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Notification.Badge" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <Button Name="btnStartPeriodicUpdate" Content="啟動一個「輪詢伺服器,而後更新 Badge」的任務" Click="btnStartPeriodicUpdate_Click_1" /> </StackPanel> </Grid> </Page>
using System;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Notification.Badge
{
public sealed partial class ScheduledBadge : Page
{
public ScheduledBadge()
{
this.InitializeComponent();
}
private void btnStartPeriodicUpdate_Click_1(object sender, RoutedEventArgs e)
{
BadgeUpdater badgeUpdater = BadgeUpdateManager.CreateBadgeUpdaterForApplication();
badgeUpdater.StartPeriodicUpdate(new Uri("https://localhost:39629/BadgeContent.xml", UriKind.Absolute), PeriodicUpdateRecurrence.HalfHour);
}
}
}
<badge version='1' value='17'/>
NotificationSetting 確認使用者是否啟用通知權限。