首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 次要磁貼開發實戰:Pin/Unpin 流程、啟動參數與視覺客製化

     編輯:關於.NET

前言:次要磁貼是應用深度連結的入口

次要磁貼 讓使用者將應用內特定內容 (某城市天氣、特定股票、聊天聯繫人、播放清單) **釘選到開始畫面**,點擊直接啟動應用並導航至該內容,無需進入主頁層層點選。這是提升應用使用頻率、支援深度連結的關鍵功能。

一、次要磁貼核心特性

  • 由應用程式碼觸發 `RequestCreateForSelectionAsync` 發起,系統彈出確認對話框,**使用者必須明確同意**。
  • 擁有**獨立視覺屬性** (Logo、Small Logo、Wide Logo、前景色、顯示名稱、Short Name)。
  • 啟動時傳遞 **`Arguments` 字串** (自定義格式),應用 `OnLaunched` 解析並導航。
  • 支援 `RequestDeleteForSelectionAsync` 取消釘選 (同樣需用戶確認)。
  • 可透過 `BadgeUpdater` / `TileUpdater` 更新動態內容 (同主要磁貼)。

次要磁貼範例

開始畫面次要磁貼

二、完整實作步驟

1. 命名空間與資源準備

using Windows.UI.StartScreen;
using Windows.Foundation;
using Windows.UI.Popups;
// 需在 StandardStyles.xaml 或頁面 Resources 定義 AppBarButton 樣式
// PinAppBarButtonStyle (內容: ), UnpinAppBarButtonStyle (內容: )

2. XAML:AppBar 放置釘選按鈕


<Page.BottomAppBar>
    <AppBar x:Name="SecondaryTileAppBar" IsSticky="False" Padding="10,0,10,0">
        <Grid>
            <StackPanel x:Name="RightPanel" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button x:Name="PinButton" Click="OnPinButtonClicked" />
            </StackPanel>
        </Grid>
    </AppBar>
</Page.BottomAppBar>

3. 程式碼後置:核心邏輯


public sealed partial class MainPage : Page {
    // 次要磁貼唯一 ID (應用內唯一,建議含業務鍵值)
    public const string SecondaryTileId = "SecondaryTile.AppBar.CityWeather";

    public MainPage() {
        InitializeComponent();
        UpdatePinButtonState(); // 頁面載入時檢查狀態
    }

    // 檢查磁貼是否存在,切換按鈕樣式
    private void UpdatePinButtonState() {
        bool exists = SecondaryTile.Exists(SecondaryTileId);
        PinButton.Style = exists ? 
            (Style)Resources["UnpinAppBarButtonStyle"] : 
            (Style)Resources["PinAppBarButtonStyle"];
    }

    // 釘選/取消釘選統一處理
    private async void OnPinButtonClicked(object sender, RoutedEventArgs e) {
        // 關鍵:設定 IsSticky=true 防止 AppBar 在彈出確認對話框時自動關閉
        SecondaryTileAppBar.IsSticky = true;

        if (SecondaryTile.Exists(SecondaryTileId)) {
            // ---- 取消釘選 ----
            var tile = new SecondaryTile(SecondaryTileId);
            // 彈出確認對話框,定位在按鈕上方
            Rect buttonRect = GetElementRect((FrameworkElement)sender);
            bool unpinned = await tile.RequestDeleteForSelectionAsync(buttonRect, Placement.Above);
            UpdatePinButtonState(); // 更新按鈕狀態
        } else {
            // ---- 釘選 ----
            // 1. 視覺屬性
            Uri squareLogo = new Uri("ms-appx:///Assets/SquareLogo.png"); // 150x150
            Uri wideLogo = new Uri("ms-appx:///Assets/WideLogo.png");     // 310x150 (可選)
            string displayName = "台北天氣";
            string shortName = "北市天氣"; // ≤13字元
            string arguments = $"city=taipei&pinnedAt={DateTime.Now:O}"; // 自定義啟動參數

            // 2. 建立 SecondaryTile 物件
            var tile = new SecondaryTile(
                SecondaryTileId,
                shortName,
                displayName,
                arguments,
                TileOptions.ShowNameOnLogo | TileOptions.ShowNameOnWideLogo, // 選項
                squareLogo
            ) {
                WideLogo = wideLogo,
                ForegroundText = ForegroundText.Dark, // 文字顏色配合 Logo 背景
                SmallLogo = new Uri("ms-appx:///Assets/SmallLogo.png") // 30x30
            };

            // 3. 發起釘選請求 (彈出系統確認對話框)
            Rect buttonRect = GetElementRect((FrameworkElement)sender);
            bool pinned = await tile.RequestCreateForSelectionAsync(buttonRect, Placement.Above);
            UpdatePinButtonState();
        }

        SecondaryTileAppBar.IsSticky = false;
    }

    // 取得按鈕相對視窗的矩形區域 (用於對話框定位)
    public Rect GetElementRect(FrameworkElement element) {
        GeneralTransform transform = element.TransformToVisual(null);
        Point point = transform.TransformPoint(new Point(0, 0));
        return new Rect(point, new Size(element.ActualWidth, element.ActualHeight));
    }
}

三、啟動參數解析與導航 (App.xaml.cs)


protected override void OnLaunched(LaunchActivatedEventArgs args) {
    // args.Arguments 即為釘選時傳入的 arguments 字串
    if (!string.IsNullOrEmpty(args.Arguments)) {
        // 解析查詢字串格式 "city=taipei&pinnedAt=..."
        var query = System.Web.HttpUtility.ParseQueryString(args.Arguments);
        string city = query["city"];
        if (!string.IsNullOrEmpty(city)) {
            // 直接導航至詳細頁,跳過主頁
            rootFrame.Navigate(typeof(WeatherDetailPage), city);
            return;
        }
    }
    // 正常啟動
    rootFrame.Navigate(typeof(MainPage));
}

四、視覺客製化最佳實踐

屬性建議規格說明
SquareLogo150×150, PNG, 透明背景中型磁貼核心圖示
WideLogo310×150, PNG寬幅磁貼 (啟用 `TileOptions.ShowNameOnWideLogo` 顯示名稱)
SmallLogo30×30, PNG應用清單、搜尋、分享來源顯示
ForegroundText`Dark` / `Light`依 Logo 主色調決定,確保文字可讀
ShowNameOnLogo / WideLogoTileOptions 旗標磁貼上直接顯示 Short Name,強化辨識度

五、執行效果展示

  1. 執行應用 → 開啟 AppBar → 點擊「釘選到開始畫面」按鈕 (圖示: 圖釘)。
  2. 系統彈出確認對話框「要將此磁貼釘選到『開始』畫面嗎?」 → 點擊「是」。
  3. 返回開始畫面,看到新磁貼 (顯示 Short Name、Logo)。
    釘選確認對話框
  4. AppBar 按鈕自動切換為「取消釘選」樣式 (圖示: 圖釘帶斜線)。
    按鈕切換狀態
  5. 點擊磁貼 → 應用啟動 → `OnLaunched` 解析 `city=taipei` → 直接進入台北天氣詳情頁。
  6. 再次點擊 AppBar「取消釘選」 → 確認對話框 → 磁貼從開始畫面移除。
    取消釘選確認

六、進階主題

  • 動態更新次要磁貼:`TileUpdateManager.CreateTileUpdaterForSecondaryTile(tileId).Update(...)` 發送本地/排程/推播通知。
  • 列舉所有次要磁貼:`await SecondaryTile.FindAllAsync()` 取得 `IReadOnlyList`,可在設定頁顯示管理列表。
  • 釘選網頁內容:`arguments` 傳遞 URL,應用啟動時在 `WebView` 載入,實現「網頁應用化」。
  • 企業部署預釘選:透過 MDM/Group Policy 佈建 `SecondaryTile` 至使用者開始畫面 (需企業版 Windows)。

總結

次要磁貼實作核心在於:**唯一 ID 設計、視覺資產準備 (三尺寸 Logo)、啟動參數結構化、AppBar 狀態同步、系統確認對話框定位**。掌握此流程,即可將應用內任意深度內容提升為開始畫面的一級入口,大幅縮短使用者觸達路徑,提升日活與留存。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved