背水一戰 Windows 10 (109) - 通知(Tile): 按計劃顯示 tile 通知, 輪詢服務端以更新 tile 通知

[源碼下載]


html

背水一戰 Windows 10 (109) - 通知(Tile): 按計劃顯示 tile 通知, 輪詢服務端以更新 tile 通知



做者:webabcd


介紹
背水一戰 Windows 10 之 通知(Tile)html5

  • 按計劃顯示 tile 通知
  • 輪詢服務端以更新 tile 通知



示例
一、演示如何按計劃顯示 tile 通知(在指定的時間顯示指定的 tile 通知,此特性在 application tile 和 secondary tile 中均支持)
Notification/Tile/Schedule.xamlc++

<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.csweb

/*
 * 演示如何按計劃顯示 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;
        }
    }
}


二、演示如何輪詢服務端以更新 tile 通知
Notification/Tile/Periodic.xamlexpress

<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.cswindows

/*
 * 演示如何輪詢服務端以更新 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(服務端代碼)api

/*
 * 用於演示「輪詢服務端以更新 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
[源碼下載]app

相關文章
相關標籤/搜索