背水一战 Windows 10 (109) - 通知(Tile): 按计划显示 tile 通知, 轮询服务端以更新 tile 通知

[源码下载]

作者:webabcd

介绍
背水一战 Windows 10 之 通知(Tile)

  • 按计划显示 tile 通知
  • 轮询服务端以更新 tile 通知

示例
1、演示如何按计划显示 tile 通知(在指定的时间显示指定的 tile 通知,此特性在 application tile 和 secondary tile 中均支持)
Notification/Tile/Schedule.xaml

<Page
    x:Class="Windows10.Notification.Tile.Schedule"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.Notification.Tile"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="10 0 10 10">

            <TextBlock Name="lblMsg" Margin="5" />

            <!--显示指定 secondary tile 的全部 ScheduledTileNotification 列表-->
            <ListBox Name="listBox" Width="800" Height="400" Margin="5" HorizontalAlignment="Left">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Id}" VerticalAlignment="Center" />
                            <TextBlock Text="{Binding Tag}" Margin="15 0 0 0" VerticalAlignment="Center" />
                            <HyperlinkButton Name="btnRemoveScheduledTile" Content="删除此 ScheduledTileNotification" Tag="{Binding Id}" Margin="15 0 0 0" Click="btnRemoveScheduledTile_Click" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

            <Button Name="btnAddScheduledTile" Content="添加指定的 ScheduledTileNotification 到指定的 secondary tile 的计划列表中" Click="btnAddScheduledTile_Click" Margin="5" />

        </StackPanel>
    </Grid>
</Page>

Notification/Tile/Schedule.xaml.cs

/*
 * 演示如何按计划显示 tile 通知(在指定的时间显示指定的 tile 通知,此特性在 application tile 和 secondary tile 中均支持)
 *
 * ScheduledTileNotification - 按计划显示的 Tile 通知
 *     Content - Tile 的内容,XmlDocument 类型的数据,只读,其需要在构造函数中指定
 *     DeliveryTime - 显示 Tile 通知的时间,只读,其需要在构造函数中指定
 *     ExpirationTime - Tile 通知的过期时间,超过这个时间就会清除这个 Tile
 *     Id - ScheduledTileNotification 的标识
 *     Tag - 在启用 tile 的队列功能时,如果 tile 的 Tag 相同则新的内容会更新旧的内容(Tag 值的前 16 个字符相同则认为是相同的 Tag)
 *         不指定的 Tag 的话则认为 Tag 都是不同的
 *
 * TileUpdater - 磁贴的 Tile 更新器
 *     AddToSchedule() - 将指定的 ScheduledTileNotification 对象添加到计划列表
 *     RemoveFromSchedule() - 从计划列表中移除指定的 ScheduledTileNotification 对象
 *     GetScheduledTileNotifications() - 获取全部 ScheduledTileNotification 对象列表
 */

using System;
using System.Collections.Generic;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using Windows.UI.StartScreen;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Windows10.Notification.Tile
{
    public sealed partial class Schedule : Page
    {
        private const string TILEID = "tile_schedule";

        public Schedule()
        {
            this.InitializeComponent();
        }

        // 在开始屏幕固定一个 secondary tile 磁贴
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            Uri square150x150Logo = new Uri("ms-appx:///Assets/Square150x150Logo.png");
            Uri wide310x150Logo = new Uri("ms-appx:///Assets/Wide310x150Logo.png");
            Uri square310x310Logo = new Uri("ms-appx:///Assets/Square310x310Logo.png");
            SecondaryTile secondaryTile = new SecondaryTile(TILEID, "name", "arguments", square150x150Logo, TileSize.Wide310x150);
            secondaryTile.VisualElements.Wide310x150Logo = wide310x150Logo;
            secondaryTile.VisualElements.Square310x310Logo = square310x310Logo;

            try
            {
                bool isPinned = await secondaryTile.RequestCreateAsync();
                lblMsg.Text = isPinned ? "固定成功" : "固定失败";
            }
            catch (Exception ex)
            {
                lblMsg.Text = "固定失败: " + ex.ToString();
            }

            ShowScheduledTiles();
        }

        // 添加指定的 ScheduledTileNotification 到指定的 secondary tile 的计划列表中
        private void btnAddScheduledTile_Click(object sender, RoutedEventArgs e)
        {
            string tileXml = $@"
                <tile>
                    <visual>
                        <binding template=‘TileSmall‘>
                            <text>Small(小){DateTime.Now.ToString("HH:mm:ss")}</text>
                        </binding>
                        <binding template=‘TileMedium‘>
                            <text>Medium(中){DateTime.Now.ToString("HH:mm:ss")}</text>
                        </binding>
                        <binding template=‘TileWide‘>
                            <text>Wide(宽){DateTime.Now.ToString("HH:mm:ss")}</text>
                        </binding>
                        <binding template=‘TileLarge‘>
                            <text>Large(大){DateTime.Now.ToString("HH:mm:ss")}</text>
                        </binding>
                    </visual>
                </tile>";

            XmlDocument tileDoc = new XmlDocument();
            tileDoc.LoadXml(tileXml);

            // 实例化 ScheduledTileNotification 对象(15 秒后显示此 Tile 通知)
            DateTime dt = DateTime.Now.AddSeconds(15);
            ScheduledTileNotification tileNotification = new ScheduledTileNotification(tileDoc, dt);

            tileNotification.Id = new Random().Next(100000, 1000000).ToString(); ;
            tileNotification.Tag = $"在 {dt.ToString("HH:mm:ss")} 时显示此 tile 通知";

            // 将指定的 ScheduledTileNotification 对象添加进指定的 secondary tile 的计划列表
            TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILEID);
            tileUpdater.AddToSchedule(tileNotification);
            tileUpdater.EnableNotificationQueue(true); // 启用 tile 的队列功能(最多可容纳 5 个 tile)

            ShowScheduledTiles();
        }

        // 删除指定 secondary tile 的指定 ScheduledTileNotification 对象
        private void btnRemoveScheduledTile_Click(object sender, RoutedEventArgs e)
        {
            string notificationId = (string)(sender as FrameworkElement).Tag;

            // 获取指定 secondary tile 的全部 ScheduledTileNotification 对象列表
            TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILEID);
            IReadOnlyList<ScheduledTileNotification> notifications = tileUpdater.GetScheduledTileNotifications();

            int notificationCount = notifications.Count;
            for (int i = 0; i < notificationCount; i++)
            {
                if (notifications[i].Id == notificationId)
                {
                    // 从计划列表中移除指定的 ScheduledTileNotification 对象
                    tileUpdater.RemoveFromSchedule(notifications[i]);
                    break;
                }
            }

            ShowScheduledTiles();
        }

        // 显示指定 secondary tile 的全部 ScheduledTileNotification 列表
        private void ShowScheduledTiles()
        {
            // 获取指定 secondary tile 的全部 ScheduledTileNotification 对象列表
            TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILEID);
            IReadOnlyList<ScheduledTileNotification> notifications = tileUpdater.GetScheduledTileNotifications();

            listBox.ItemsSource = notifications;
        }
    }
}

2、演示如何轮询服务端以更新 tile 通知
Notification/Tile/Periodic.xaml

<Page
    x:Class="Windows10.Notification.Tile.Periodic"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.Notification.Tile"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="10 0 10 10">

            <TextBlock Name="lblMsg" Margin="5" />

            <Button Name="btnStartPeriodicUpdate" Content="启动一个“轮询服务端获取数据,然后更新 Tile 通知”的任务" Click="btnStartPeriodicUpdate_Click" Margin="5" />

        </StackPanel>
    </Grid>
</Page>

Notification/Tile/Periodic.xaml.cs

/*
 * 演示如何轮询服务端以更新 tile 通知
 *
 * TileUpdater - 磁贴的 Tile 更新器
 *     StartPeriodicUpdate(Uri tileContent, DateTimeOffset startTime, PeriodicUpdateRecurrence requestedInterval) - 启动一个“轮询服务端获取数据,然后更新 Tile 通知”的任务
 *     StartPeriodicUpdateBatch(IEnumerable<Uri> tileContents, DateTimeOffset startTime, PeriodicUpdateRecurrence requestedInterval) - 启动一个“轮询服务端获取数据,然后更新 Tile 通知”的任务
 *         tileContent - Tile 通知的内容(xml 格式数据)的 uri 地址(通过 StartPeriodicUpdateBatch 方法指定多个则会循环显示)
 *         startTime - 可以指定启动此任务的时间
 *             指定此值时的逻辑为:首先会立刻请求服务端获取数据,然后在到达 startTime 指定的时间点后再次获取数据,最后再每次按 requestedInterval 指定的间隔轮询服务端
 *         requestedInterval - 轮询服务端的周期(PeriodicUpdateRecurrence 枚举)
 *             HalfHour, Hour, SixHours, TwelveHours, Daily
 *     StopPeriodicUpdate() - 停止“轮询服务端获取数据,然后更新 Tile 通知”的任务
 *
 *
 * 注:服务端代码请参见 WebApi/Controllers/TileContentController.cs(有指定 X-WNS-Expires 标头和 X-WNS-Tag 标头的示例)
 */

using System;
using Windows.UI.Notifications;
using Windows.UI.StartScreen;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Windows10.Notification.Tile
{
    public sealed partial class Periodic : Page
    {
        private const string TILEID = "tile_periodic";

        public Periodic()
        {
            this.InitializeComponent();
        }

        // 在开始屏幕固定一个 secondary tile 磁贴
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            Uri square150x150Logo = new Uri("ms-appx:///Assets/Square150x150Logo.png");
            Uri wide310x150Logo = new Uri("ms-appx:///Assets/Wide310x150Logo.png");
            Uri square310x310Logo = new Uri("ms-appx:///Assets/Square310x310Logo.png");
            SecondaryTile secondaryTile = new SecondaryTile(TILEID, "name", "arguments", square150x150Logo, TileSize.Wide310x150);
            secondaryTile.VisualElements.Wide310x150Logo = wide310x150Logo;
            secondaryTile.VisualElements.Square310x310Logo = square310x310Logo;

            try
            {
                bool isPinned = await secondaryTile.RequestCreateAsync();
                lblMsg.Text = isPinned ? "固定成功" : "固定失败";
            }
            catch (Exception ex)
            {
                lblMsg.Text = "固定失败: " + ex.ToString();
            }
        }

        // 启动一个“轮询服务端获取数据,然后更新 Tile 通知”的任务
        private void btnStartPeriodicUpdate_Click(object sender, RoutedEventArgs e)
        {
            // 启动一个循环更新 Tile 通知的任务,并指定 Tile 通知的数据源和轮询周期
            TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILEID);
            tileUpdater.EnableNotificationQueue(true); // 启用 tile 的队列功能(最多可容纳 5 个 tile)

            // 马上请求服务端获取数据,然后 45 分钟之后再次获取数据,最后再每半个小时获取一次数据
            tileUpdater.StartPeriodicUpdate(new Uri("http://localhost:44914/api/TileContent", UriKind.Absolute), DateTimeOffset.UtcNow.AddMinutes(45), PeriodicUpdateRecurrence.HalfHour);

            // Tile 通知的数据源示例请参见 WebApi/Controllers/TileContentController.cs
        }
    }
}

/WebApi/Controllers/TileContentController.cs(服务端代码)

/*
 * 用于演示“轮询服务端以更新 tile 通知”的服务端部分
 */

using System;
using System.Net.Http;
using System.Text;
using System.Web.Http;

namespace WebApi.Controllers
{
    public class TileContentController : ApiController
    {
        private Random _random = new Random();

        [HttpGet]
        public HttpResponseMessage Get()
        {
            string tileXml = $@"
                <tile>
                    <visual>
                        <binding template=‘TileSmall‘>
                            <text>Small(小){DateTime.Now.ToString("HH:mm:ss")}</text>
                        </binding>
                        <binding template=‘TileMedium‘>
                            <text>Medium(中){DateTime.Now.ToString("HH:mm:ss")}</text>
                        </binding>
                        <binding template=‘TileWide‘>
                            <text>Wide(宽){DateTime.Now.ToString("HH:mm:ss")}</text>
                        </binding>
                        <binding template=‘TileLarge‘>
                            <text>Large(大){DateTime.Now.ToString("HH:mm:ss")}</text>
                        </binding>
                    </visual>
                </tile>";

            HttpResponseMessage result = new HttpResponseMessage
            {
                Content = new StringContent(tileXml, Encoding.UTF8, "text/html")
            };

            // Tile 通知的过期时间,超过这个时间就会清除这个 Tile(对于“轮询服务端以更新 Tile 通知”来说,如果不指定此值,则默认 3 天后过期)
            // 通过 ToString("R") 可以把日期格式化为“RFC 1123”格式
            result.Headers.Add("X-WNS-Expires", DateTime.UtcNow.AddSeconds(60).ToString("R")); // 60 秒后过期

            // 在启用 tile 的队列功能时,如果 tile 的 Tag 相同则新的内容会更新旧的内容(Tag 值的前 16 个字符相同则认为是相同的 Tag)
            // 不指定的 Tag 的话则认为 Tag 都是不同的
            result.Headers.Add("X-WNS-Tag", _random.Next().ToString());

            return result;
        }
    }
}

OK
[源码下载]

原文地址:https://www.cnblogs.com/webabcd/p/9206975.html

时间: 2024-10-12 04:07:56

背水一战 Windows 10 (109) - 通知(Tile): 按计划显示 tile 通知, 轮询服务端以更新 tile 通知的相关文章

背水一战 Windows 10 (111) - 通知(Tile): secondary tile 模板之图片, secondary tile 模板之分组

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 通知(Tile) secondary tile 模板之图片 secondary tile 模板之分组 示例1.本例用于演示 tile 显示模板的图片相关的知识点Notification/Tile/TemplateImage.xaml <Page x:Class="Windows10.Notification.Tile.TemplateImage" xmlns="http://schemas.mi

背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知)

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 后台下载任务(任务分组,并行或串行执行,组完成后通知) 示例演示后台下载任务的分组,以及如何设置组内任务是并行执行还是串行执行,以及组任务全部完成后如何 toast 或 tile 通知)BackgroundTask/TransferModel.cs /* * 扩展了 DownloadOperation 和 UploadOperation,用于 MVVM 绑定数据 */ using System; using S

背水一战 Windows 10 (121) - 后台任务: 推送通知

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 推送通知 示例演示如何接收推送通知/WebApi/PushNotificationController.cs /* * 演示如何向 app 推送通知 * 由于本例没有上商店,所以本例是无法演示的,需要看演示效果的话运行一下自己写的“打字通”的 /TypingGame/PushNotification/Sample.xaml,然后用其生成的 channel 地址在 /WebApi/Controllers/Push

背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 绑定 通过 Binding 绑定对象 通过 x:Bind 绑定对象 通过 Binding 绑定集合 通过 x:Bind 绑定集合 示例1.演示如何通过 Binding 绑定对象Bind/BindingModel.xaml <Page x:Class="Windows10.Bind.BindingModel" xmlns="http://schemas.microsoft.com/winfx/20

背水一战 Windows 10 (74) - 控件(控件基类): UIElement - 与 CanDrag 相关的事件, 与 AllowDrop 相关的事件

原文:背水一战 Windows 10 (74) - 控件(控件基类): UIElement - 与 CanDrag 相关的事件, 与 AllowDrop 相关的事件 [源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 控件(控件基类 - UIElement) 与 CanDrag 相关的事件(DragStartingEventArgs, DropCompletedEventArgs) 与 AllowDrop 相关的事件(DragEventArgs) 示例1.演示 UIEle

背水一战 Windows 10 (102) - 应用间通信: 剪切板

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 应用间通信 剪切板 - 基础, 复制/粘贴 text 内容 剪切板 - 复制/粘贴 html 内容 剪切板 - 复制/粘贴 bitmap 内容,延迟复制 剪切板 - 复制/粘贴文件 示例1.演示剪切板的基础知识,以及如何复制 text 数据到剪切板,以及如何从剪切板中获取 text 数据 App2AppCommunication/Clipboard.xaml <Page x:Class="Windows10.App

背水一战 Windows 10 (119) - 后台任务: 后台下载任务(任务分组,组完成后触发后台任务)

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 后台下载任务(任务分组,组完成后触发后台任务) 示例演示后台下载任务的分组,以及组任务全部完成后如何触发后台任务/BackgroundTaskLib/BackgroundTaskTransfer.cs /* * 后台任务,用于演示指定的一组后台下载任务全部完成后如何触发此后台任务 * * BackgroundTransferCompletionGroup - 分组对象(用于实现“组任务全部完成后触发后台任务”)

背水一战 Windows 10 (120) - 后台任务: 后台上传任务

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 后台上传任务 示例演示 uwp 的后台上传任务BackgroundTask/TransferModel.cs /* * 扩展了 DownloadOperation 和 UploadOperation,用于 MVVM 绑定数据 */ using System; using System.ComponentModel; using Windows.Networking.BackgroundTransfer; nam

背水一战 Windows 10 (40) - 控件(导航类): AppBar, CommandBar

原文:背水一战 Windows 10 (40) - 控件(导航类): AppBar, CommandBar [源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 控件(导航类) AppBar CommandBar 示例1.AppBar 的示例Controls/NavigationControl/AppBarDemo.xaml <Page x:Class="Windows10.Controls.NavigationControl.AppBarDemo" xml