Share via


對話方塊控制項

對話方塊控制項是提供內容相關應用程式資訊的強制回應 UI 重疊項目。 這些項目會阻擋與應用程式視窗的互動,直到對話方塊確實關閉為止, 而且對話方塊通常會需要使用者執行某種動作。

Example of a dialog

這是正確的控制項嗎?

使用對話方塊來通知使用者重要的資訊,或是在完成動作之前要求確認或其他資訊。

如需使用對話方塊和使用飛出視窗 (類似的控制項) 之時機的建議,請參閱對話方塊和飛出視窗

一般 指導方針

  • 在對話方塊文字的第一行中清楚地標識問題或使用者的目標。
  • 對話方塊標題是主要說明,這是選擇性的。
    • 使用簡短的標題來說明人員需要對對話方塊執行什麼動作。
    • 如果您使用該對話方塊傳遞簡單的訊息、錯誤或問題,則可以選擇省略標題。 依靠內容文字來傳遞核心訊息。
    • 請確定標題與按鈕選項直接相關。
  • 對話方塊內容包含描述性文字,這是必填。
    • 盡量簡單地呈現訊息、錯誤或封鎖問題。
    • 如果使用對話方塊標題,請使用內容區域提供更多詳細資訊或定義術語。 請勿以只有些微差異的用字重複標題。
  • 必須至少顯示一個對話方塊按鈕。
    • 確保對話方塊至少有一個對應於安全、非破壞性動作的按鈕,例如 [了解!]、[關閉] 或 [取消]。 使用 CloseButton API 來新增此按鈕。
    • 使用對主要指示或內容的明確回應作為按鈕文字。 例如,「您想允許 AppName 存取您的位置嗎?」,後面接著 [允許] 和 [封鎖] 按鈕。 這可以讓人更快地理解特定反應,進而有效率地做出決策。
    • 確保動作按鈕的文字簡潔扼要。 簡短字串可讓使用者快速且放心地進行選擇。
    • 除了安全、不具破壞性的動作之外,還可以選擇性地向使用者顯示一個或兩個與主要指示相關的動作按鈕。 這些「執行」動作按鈕可確認對話方塊的要點。 使用 PrimaryButton 和 SecondaryButton API 來新增這些「執行」動作。
    • 「執行」動作按鈕應該顯示為最左側按鈕。 安全、不具破壞性的動作應該顯示為最右側按鈕。
    • 您可以隨意選擇將三個按鈕其中之一區分為對話方塊的預設按鈕。 使用 DefaultButton API 來區分其中一個按鈕。
  • 請勿使用對話方塊來處理與頁面上特定位置相關的錯誤,例如驗證錯誤 (如在密碼欄位中),使用應用程式的畫布來顯示內嵌錯誤。
  • 使用 ContentDialog 類別建置您的對話方塊體驗。 請勿使用已過時的 MessageDialog API。

UWP 和 WinUI 2

重要

本文中的資訊和範例針對使用 Windows App SDKWinUI 3 的應用程式進行了最佳化,但通常適用於使用 WinUI 2 的 UWP 應用程式。 如需平台特定資訊和範例,請參閱 UWP API 參考。

本節包含您在 UWP 或 WinUI 2 應用程式中使用控制項所需的資訊。

此控制項的 API 位在 Windows.UI.Xaml.Controls 命名空間中。

建議使用最新的 WinUI 2 來取得所有控制項的最新樣式和範本。 WinUI 2.2 或更新版本包含此使用圓角之控制項的新範本。 如需詳細資訊,請參閱圓角半徑

建立對話方塊

WinUI 3 資源庫應用程式包含大多數 WinUI 3 控制項和功能的互動式範例。 從 Microsoft Store 取得應用程式,或在 GitHub 上取得原始程式碼

若要建立對話方塊,請使用 ContentDialog 類別。 您可以用程式碼或標記建立對話方塊。 雖然在 XAML 中定義 UI 元素通常會比較輕鬆,但在簡易對話方塊的情況下,使用程式碼會更容易。 此範例會建立一個對話方塊來通知使用者沒有 WiFi 連線,然後使用 ShowAsync 方法來顯示。

private async void DisplayNoWifiDialog()
{
    ContentDialog noWifiDialog = new ContentDialog
    {
        Title = "No wifi connection",
        Content = "Check your connection and try again.",
        CloseButtonText = "Ok"
    };

    ContentDialogResult result = await noWifiDialog.ShowAsync();
}

當使用者點擊對話方塊按鈕時,ShowAsync 方法會傳回 ContentDialogResult 以讓您知道使用者點擊了哪個按鈕。

此範例中的對話方塊會提出問題,並使用傳回的 ContentDialogResult 來確定使用者的回應。

private async void DisplayDeleteFileDialog()
{
    ContentDialog deleteFileDialog = new ContentDialog
    {
        Title = "Delete file permanently?",
        Content = "If you delete this file, you won't be able to recover it. Do you want to delete it?",
        PrimaryButtonText = "Delete",
        CloseButtonText = "Cancel"
    };

    ContentDialogResult result = await deleteFileDialog.ShowAsync();

    // Delete the file if the user clicked the primary button.
    /// Otherwise, do nothing.
    if (result == ContentDialogResult.Primary)
    {
        // Delete the file.
    }
    else
    {
        // The user clicked the CloseButton, pressed ESC, Gamepad B, or the system back button.
        // Do nothing.
    }
}

提供安全的動作

因為對話方塊會封鎖使用者互動,又因為按鈕是使用者關閉對話方塊的主要機制,所以務必在對話方塊中包含至少一個「安全」且不具破壞性的按鈕,例如 [關閉] 或 [了解!]。 所有對話方塊都必須至少包含一個要關閉對話方塊的安全動作按鈕。 這可確保使用者放心地在不執行動作的情況下關閉對話方塊。
An one button dialog

private async void DisplayNoWifiDialog()
{
    ContentDialog noWifiDialog = new ContentDialog
    {
        Title = "No wifi connection",
        Content = "Check your connection and try again.",
        CloseButtonText = "Ok"
    };

    ContentDialogResult result = await noWifiDialog.ShowAsync();
}

使用對話方塊來顯示阻斷式問題時,對話方塊應該向使用者顯示與問題相關的動作按鈕。 「安全」且不具破壞性的按鈕可能會伴隨一個或兩個「執行」動作按鈕。 向使用者顯示多個選項時,請確定按鈕已清楚說明與所提問題相關的「執行」和安全/「不執行」動作。

A two button dialog

private async void DisplayLocationPromptDialog()
{
    ContentDialog locationPromptDialog = new ContentDialog
    {
        Title = "Allow AppName to access your location?",
        Content = "AppName uses this information to help you find places, connect with friends, and more.",
        CloseButtonText = "Block",
        PrimaryButtonText = "Allow"
    };

    ContentDialogResult result = await locationPromptDialog.ShowAsync();
}

向使用者提供兩個「執行」動作和一個「不執行」動作時,您會使用三按鈕對話方塊。 三按鈕對話方塊應在明確區分次要動作與安全/關閉動作的情況下謹慎使用。

A three button dialog

private async void DisplaySubscribeDialog()
{
    ContentDialog subscribeDialog = new ContentDialog
    {
        Title = "Subscribe to App Service?",
        Content = "Listen, watch, and play in high definition for only $9.99/month. Free to try, cancel anytime.",
        CloseButtonText = "Not Now",
        PrimaryButtonText = "Subscribe",
        SecondaryButtonText = "Try it"
    };

    ContentDialogResult result = await subscribeDialog.ShowAsync();
}

三按鈕對話方塊

ContentDialog 有三個不同類型的按鈕,您可以用來建置對話方塊體驗。

  • CloseButton (必要):表示可讓使用者結束對話方塊的安全、非破壞性動作。 顯示為最右側按鈕。
  • PrimaryButton (選擇性):表示第一個「執行」動作。 顯示為最左側按鈕。
  • SecondaryButton (選擇性):表示第二個「執行」動作。 顯示為中間按鈕。

使用內建按鈕會適當安排按鈕位置、確保其正確回應鍵盤事件、確認即使即使螢幕小鍵盤已啟動也能保持命令區域在可見狀態,並且讓對話方塊與其他對話方塊保持一致的外觀。

CloseButton

每個對話方塊都必須包含可讓使用者放心結束對話方塊的安全、非破壞性按鈕。

使用 ContentDialog.CloseButton API 來建立此按鈕。 這可讓您為所有輸入 (包括滑鼠、鍵盤、觸控和遊戲台) 建立適當的使用者體驗。 這個體驗出現的時機:

  • 使用者按一下或點選 CloseButton。
  • 使用者按下系統返回按鈕。
  • 使用者按下鍵盤的 ESC 按鈕。
  • 使用者按下遊戲遙控器 B 按鈕。

當使用者點擊對話方塊按鈕時,ShowAsync 方法會傳回 ContentDialogResult 以讓您知道使用者點擊了哪個按鈕。 按下 CloseButton 會傳回 ContentDialogResult.None。

PrimaryButton 和 SecondaryButton

除了 CloseButton 之外,還可以選擇性地向使用者顯示一個或兩個與主要指示相關的動作按鈕。 將 PrimaryButton 運用在第一個「執行」動作,並將 SecondaryButton 運用在第二個「執行」動作。 在三按鈕對話方塊中,PrimaryButton 通常表示肯定「執行」動作,而 SecondaryButton 通常表示中性或次要「執行」動作。 例如,應用程式可能會提示使用者訂閱一項服務。 負責肯定「執行」動作的 PrimaryButton 會主控「訂閱」文字,而負責中性「執行」動作的 SecondaryButton 則主控「試用」文字。 CloseButton 可讓使用者不執行任一動作就取消。

當使用者按一下 PrimaryButton 時,ShowAsync 方法會傳回 ContentDialogResult.Primary。 當使用者按一下 SecondaryButton 時,ShowAsync 方法會傳回 ContentDialogResult.Secondary。

A three button dialog

DefaultButton

您可以隨意選擇將三個按鈕其中之一區分為預設按鈕。 指定預設按鈕會導致發生下列情況:

  • 按鈕將會獲得輔色按鈕視覺效果處理
  • 按鈕將會自動回應 ENTER 鍵
    • 當使用者按下鍵盤的 ENTER 鍵時,與預設按鈕相關聯的按一下處理常式將會觸發,而 ContentDialogResult 則會傳回與預設按鈕相關聯的值
    • 如果使用者將鍵盤焦點放在處理 ENTER 的控制項上,預設按鈕便不會回應 ENTER 按下動作
  • 除非對話方塊內容包含可設定焦點的 UI,否則按鈕在開啟對話方塊時都會自動取得焦點

使用 ContentDialog.DefaultButton 屬性來表示預設按鈕。 預設不會設定任何預設按鈕。

A three button dialog with a default button

private async void DisplaySubscribeDialog()
{
    ContentDialog subscribeDialog = new ContentDialog
    {
        Title = "Subscribe to App Service?",
        Content = "Listen, watch, and play in high definition for only $9.99/month. Free to try, cancel anytime.",
        CloseButtonText = "Not Now",
        PrimaryButtonText = "Subscribe",
        SecondaryButtonText = "Try it",
        DefaultButton = ContentDialogButton.Primary
    };

    ContentDialogResult result = await subscribeDialog.ShowAsync();
}

確認對話方塊 (確定/取消)

確認對話方塊可讓使用者有機會確認他們想要執行動作。 他們可以確認動作,或選擇取消。 典型的確認對話方塊有兩個按鈕:確認 (「確定」) 按鈕和取消按鈕。

  • 一般來說,確認按鈕應位於左側 (主要按鈕),取消按鈕 (次要按鈕) 應位於右側。

    An OK/cancel dialog
  • 如通用建議一節所述,使用具有文字的按鈕來標識對主要說明或內容的特定回應。

有些平台會將確認按鈕放在右側而不是左側。 為什麼我們建議將確認按鈕放在左側呢? 如果您假設大多數使用者都慣用右手,並且他們用那隻手握住手機,那麼當確認按鈕位於左側時,點選確認按鈕的動作會比較順,因為該按鈕較可能位於使用者的拇指弧內。畫面右側的按鈕會讓使用者將拇指向內拉到不太舒服的位置。

ContentDialog AppWindow 或 Xaml Islands

請注意:這一節僅適用於目標為 Windows 10 版本 1903 或更新版本的應用程式。 AppWindow 和 XAML Islands 不適用於舊版。 如需版本設定的詳細資訊,請參閱版本調適型應用程式

根據預設,內容對話方塊顯示強制相對於根目錄 ApplicationView。 當您使用 AppWindowXAML Island 內的 ContentDialog 時,您需要在對話方塊上將 XamlRoot 手動設為 XAML 主機的根目錄。

若要這麼做,請將 ContentDialog 的 XamlRoot 屬性設定為與 AppWindow 或 XAML Island 中現有元素相同的 XamlRoot,如下所示。

private async void DisplayNoWifiDialog()
{
    ContentDialog noWifiDialog = new ContentDialog
    {
        Title = "No wifi connection",
        Content = "Check your connection and try again.",
        CloseButtonText = "Ok"
    };

    // Use this code to associate the dialog to the appropriate AppWindow by setting
    // the dialog's XamlRoot to the same XamlRoot as an element that is already present in the AppWindow.
    if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
    {
        noWifiDialog.XamlRoot = elementAlreadyInMyAppWindow.XamlRoot;
    }

    ContentDialogResult result = await noWifiDialog.ShowAsync();
}

警告

每個執行緒一次只能開啟一個 ContentDialog。 嘗試開啟兩個 ContentDialogs 會擲回例外狀況,即使它們嘗試在不同的 AppWindows 中開啟。

取得範例程式碼