對話方塊控制項Dialog controls

對話方塊控制項是提供內容相關應用程式資訊的強制回應 UI 重疊項目。Dialog controls are modal UI overlays that provide contextual app information. 這些項目會阻擋與應用程式視窗的互動,直到對話方塊確實關閉為止,They block interactions with the app window until being explicitly dismissed. 而且它們通常會需要使用者執行某種動作。They often request some kind of action from the user.

對話方塊範例

取得 Windows UI 程式庫Get the Windows UI Library

WinUI 標誌

Windows UI 程式庫 2.2 或更新版本中有這個控制項使用圓角的新範本。Windows UI Library 2.2 or later includes a new template for this control that uses rounded corners. 如需詳細資訊,請參閱圓角半徑For more info, see Corner radius. WinUI 是 NuGet 套件,其中包含適用於 Windows 應用程式的新控制項和 UI 功能。WinUI is a NuGet package that contains new controls and UI features for Windows apps. 如需詳細資訊 (包括安裝指示),請參閱 Windows UI 程式庫For more info, including installation instructions, see Windows UI Library.

平台 API: ContentDialog 類別Platform APIs: ContentDialog class

這是正確的控制項嗎?Is this the right control?

使用對話方塊來通知使用者重要的資訊,或是在完成動作之前要求確認或其他資訊。Use dialogs to notify users of important information or to request confirmation or additional info before an action can be completed.

如需使用對話方塊和使用飛出視窗 (類似的控制項) 之時機的建議,請參閱對話方塊和飛出視窗For recommendations on when to use a dialog vs. when to use a flyout (a similar control), see Dialogs and flyouts.

範例Examples

XAML 控制項庫XAML Controls Gallery
XAML controls gallery

如果您已安裝 XAML 控制項庫應用程式,請按一下這裡開啟應用程式並查看 ContentDialogFlyout 運作情形。If you have the XAML Controls Gallery app installed, click here to open the app and see the ContentDialog or Flyout in action.

一般指導方針General guidelines

  • 在對話方塊文字的第一行中明確識別問題或使用者的目標。Clearly identify the issue or the user's objective in the first line of the dialog's text.
  • 對話方塊標題是主要指示,而且是選擇性的。The dialog title is the main instruction and is optional.
    • 使用簡短標題來說明使用者需使用對話方塊執行什麼動作。Use a short title to explain what people need to do with the dialog.
    • 如果您使用對話方塊來傳達簡單的訊息、錯誤或問題,可以選擇性地省略標題。If you're using the dialog to deliver a simple message, error or question, you can optionally omit the title. 只需要內容文字傳達核心資訊即可。Rely on the content text to deliver that core information.
    • 確定標題與按鈕選項直接相關。Make sure that the title relates directly to the button choices.
  • 對話方塊內容包含描述性文字,而且是必要的。The dialog content contains the descriptive text and is required.
    • 盡可能簡要地呈現訊息、錯誤或造成應用程式無法繼續執行的問題。Present the message, error, or blocking question as simply as possible.
    • 使用對話方塊標題時,請利用內容區域提供更多詳細資料或定義詞彙。If a dialog title is used, use the content area to provide more detail or define terminology. 不要以只有些微差異的用字重複標題。Don't repeat the title with slightly different wording.
  • 至少必須顯示一個對話方塊按鈕。At least one dialog button must appear.
    • 確保對話方塊至少有一個對應於安全、非破壞性動作的按鈕,例如 [了解!]、[關閉] 或 [取消]。Ensure that your dialog has at least one button corresponding to a safe, nondestructive action like "Got it!", "Close", or "Cancel". 使用 CloseButton API 來新增此按鈕。Use the CloseButton API to add this button.
    • 使用對主要指示或內容的明確回應作為按鈕文字。Use specific responses to the main instruction or content as button text. 例如,「是否允許 AppName 存取您的位置?」,後面接 [允許] 和 [封鎖] 按鈕。An example is, "Do you want to allow AppName to access your location?", followed by "Allow" and "Block" buttons. 明確的回應讓人更快速理解,可以更有效率地做出決定。Specific responses can be understood more quickly, resulting in efficient decision making.
    • 確保動作按鈕的文字簡潔扼要。Ensure that the text of the action buttons is concise. 簡短字串可讓使用者快速且放心地進行選擇。Short strings enable the user to make a choice quickly and confidently.
    • 除了安全、不具破壞性的動作之外,還可以選擇性地向使用者顯示一個或兩個與主要指示相關的動作按鈕。In addition to the safe, nondestructive action, you may optionally present the user with one or two action buttons related to the main instruction. 這些「執行」動作按鈕可確認對話方塊的要點。These "do it" action buttons confirm the main point of the dialog. 使用 PrimaryButton 和 SecondaryButton API 來新增這些「執行」動作。Use the PrimaryButton and SecondaryButton APIs to add these "do it" actions.
    • 「執行」動作按鈕應該顯示為最左側按鈕。The "do it" action button(s) should appear as the leftmost buttons. 安全、不具破壞性的動作應該顯示為最右側按鈕。The safe, nondestructive action should appear as the rightmost button.
    • 您可以隨意選擇將三個按鈕其中之一區分為對話方塊的預設按鈕。You may optionally choose to differentiate one of the three buttons as the dialog's default button. 使用 DefaultButton API 來區分其中一個按鈕。Use the DefaultButton API to differentiate one of the buttons.
  • 針對頁面上特定位置的內容相關錯誤,例如 (密碼欄位中的) 驗證錯誤,請使用 App 本身的畫布顯示內嵌錯誤,而不要使用對話方塊。Don't use dialogs for errors that are contextual to a specific place on the page, such as validation errors (in password fields, for example), use the app's canvas itself to show inline errors.
  • 使用 ContentDialog 類別建置您的對話方塊體驗。Use the ContentDialog class to build your dialog experience. 請勿使用已過時的 MessageDialog API。Don't use the deprecated MessageDialog API.

如何建立對話方塊How to create a dialog

若要建立對話方塊,請使用 ContentDialog 類別To create a dialog, you use the ContentDialog class. 您可以利用程式碼或標記建立對話方塊。You can create a dialog in code or markup. 雖然在 XAML 中定義 UI 元素通常會比較容易,但針對簡單的對話方塊,單純使用程式碼會較為容易。Although its usually easier to define UI elements in XAML, in the case of a simple dialog, it's actually easier to just use code. 這個範例會建立一個對話方塊,以通知使用者沒有 WiFi 連線,然後使用 ShowAsync 方法來加以顯示。This example creates a dialog to notify the user that there's no WiFi connection, and then uses the ShowAsync method to display it.

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,讓您知道使用者按下哪一個按鈕。When the user clicks a dialog button, the ShowAsync method returns a ContentDialogResult to let you know which button the user clicks.

這個範例中的對話方塊會提問,並使用傳回的 ContentDialogResult 來判斷使用者的回應。The dialog in this example asks a question and uses the returned ContentDialogResult to determine the user's response.

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

提供安全的動作Provide a safe action

因為對話方塊會封鎖使用者互動,又因為按鈕是使用者關閉對話方塊的主要機制,所以務必在對話方塊中包含至少一個「安全」且不具破壞性的按鈕,例如 [關閉] 或 [了解!]。Because dialogs block user interaction, and because buttons are the primary mechanism for users to dismiss the dialog, ensure that your dialog contains at least one "safe" and nondestructive button such as "Close" or "Got it!". 所有對話方塊都必須至少包含一個要關閉對話方塊的安全動作按鈕。All dialogs should contain at least one safe action button to close the dialog. 這可確保使用者放心地在不執行動作的情況下關閉對話方塊。This ensures that the user can confidently close the dialog without performing an action.
單按鈕對話方塊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();
}

使用對話方塊來顯示阻斷式問題時,對話方塊應該向使用者顯示與問題相關的動作按鈕。When dialogs are used to display a blocking question, your dialog should present the user with action buttons related to the question. 「安全」且不具破壞性的按鈕可能會伴隨一個或兩個「執行」動作按鈕。The "safe" and nondestructive button may be accompanied by one or two "do it" action buttons. 向使用者顯示多個選項時,請確定按鈕已清楚說明與所提問題相關的「執行」和安全/「不執行」動作。When presenting the user with multiple options, ensure that the buttons clearly explain the "do it" and safe/"don't do it" actions related to the question proposed.

雙按鈕對話方塊

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();
}

向使用者提供兩個「執行」動作和一個「不執行」動作時,您會使用三按鈕對話方塊。Three button dialogs are used when you present the user with two "do it" actions and a "don't do it" action. 三按鈕對話方塊應在明確區分次要動作與安全/關閉動作的情況下謹慎使用。Three button dialogs should be used sparingly with clear distinctions between the secondary action and the safe/close action.

三按鈕對話方塊

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();
}

三按鈕對話方塊The three dialog buttons

ContentDialog 有三個不同類型的按鈕,您可以用來建置對話方塊體驗。ContentDialog has three different types of buttons that you can use to build a dialog experience.

  • CloseButton (必要):表示可讓使用者結束對話方塊的安全、非破壞性動作。CloseButton - Required - Represents the safe, nondestructive action that enables the user to exit the dialog. 顯示為最右側按鈕。Appears as the rightmost button.
  • PrimaryButton (選擇性):表示第一個「執行」動作。PrimaryButton - Optional - Represents the first "do it" action. 顯示為最左側按鈕。Appears as the leftmost button.
  • SecondaryButton (選擇性):表示第二個「執行」動作。SecondaryButton - Optional - Represents the second "do it" action. 顯示為中間按鈕。Appears as the middle button.

使用內建按鈕會適當安排按鈕位置、確保其正確回應鍵盤事件、確認即使即使螢幕小鍵盤已啟動也能保持命令區域在可見狀態,並且讓對話方塊與其他對話方塊保持一致的外觀。Using the built-in buttons will position the buttons appropriately, ensure that they correctly respond to keyboard events, ensure that the command area remains visible even when the on-screen keyboard is up, and will make the dialog look consistent with other dialogs.

CloseButtonCloseButton

每個對話方塊都必須包含可讓使用者放心結束對話方塊的安全、非破壞性按鈕。Every dialog should contain a safe, nondestructive action button that enables the user to confidently exit the dialog.

使用 ContentDialog.CloseButton API 來建立此按鈕。Use the ContentDialog.CloseButton API to create this button. 這可讓您為所有輸入 (包括滑鼠、鍵盤、觸控和遊戲台) 建立適當的使用者體驗。This allows you to create the right user experience for all inputs including mouse, keyboard, touch, and gamepad. 這個體驗出現的時機:This experience will happen when:

  1. 使用者按一下或點選 CloseButtonThe user clicks or taps on the CloseButton
  2. 使用者按下系統返回按鈕The user presses the system back button
  3. 使用者按下鍵盤的 ESC 按鈕The user presses the ESC button on the keyboard
  4. 使用者按下遊戲台 B 按鈕The user presses Gamepad B

當使用者按一下對話方塊按鈕時,ShowAsync 方法會傳回 ContentDialogResult,讓您知道使用者按下哪一個按鈕。When the user clicks a dialog button, the ShowAsync method returns a ContentDialogResult to let you know which button the user clicks. 按下 CloseButton 會傳回 ContentDialogResult.None。Pressing on the CloseButton returns ContentDialogResult.None.

PrimaryButton 和 SecondaryButtonPrimaryButton and SecondaryButton

除了 CloseButton 之外,還可以選擇性地向使用者顯示一個或兩個與主要指示相關的動作按鈕。In addition to the CloseButton, you may optionally present the user with one or two action buttons related to the main instruction. 將 PrimaryButton 運用在第一個「執行」動作,並將 SecondaryButton 運用在第二個「執行」動作。Leverage PrimaryButton for the first "do it" action, and SecondaryButton for the second "do it" action. 在三按鈕對話方塊中,PrimaryButton 通常表示肯定「執行」動作,而 SecondaryButton 通常表示中性或次要「執行」動作。In three-button dialogs, the PrimaryButton generally represents the affirmative "do it" action, while the SecondaryButton generally represents a neutral or secondary "do it" action. 例如,應用程式可能會提示使用者訂閱一項服務。For example, an app may prompt the user to subscribe to a service. 負責肯定「執行」動作的 PrimaryButton 會主控「訂閱」文字,而負責中性「執行」動作的 SecondaryButton 則主控「試用」文字。The PrimaryButton as the affirmative "do it" action would host the Subscribe text, while the SecondaryButton as the neutral "do it" action would host the Try it text. CloseButton 可讓使用者不執行任一動作就取消。The CloseButton would allow the user to cancel without performing either action.

當使用者按一下 PrimaryButton 時,ShowAsync 方法會傳回 ContentDialogResult.Primary。When the user clicks on the PrimaryButton, the ShowAsync method returns ContentDialogResult.Primary. 當使用者按一下 SecondaryButton 時,ShowAsync 方法會傳回 ContentDialogResult.Secondary。When the user clicks on the SecondaryButton, the ShowAsync method returns ContentDialogResult.Secondary.

三按鈕對話方塊

DefaultButtonDefaultButton

您可以隨意選擇將三個按鈕其中之一區分為預設按鈕。You may optionally choose to differentiate one of the three buttons as the default button. 指定預設按鈕會導致發生下列情況:Specifying the default button causes the following to happen:

  • 按鈕將會獲得輔色按鈕視覺效果處理The button receives the Accent Button visual treatment
  • 按鈕將會自動回應 ENTER 鍵The button will respond to the ENTER key automatically
    • 當使用者按下鍵盤的 ENTER 鍵時,與預設按鈕相關聯的按一下處理常式將會觸發,而 ContentDialogResult 則會傳回與預設按鈕相關聯的值When the user presses the ENTER key on the keyboard, the click handler associated with the Default Button will fire and the ContentDialogResult will return the value associated with the Default Button
    • 如果使用者將鍵盤焦點放在處理 ENTER 的控制項上,預設按鈕便不會回應 ENTER 按下動作If the user has placed Keyboard Focus on a control that handles ENTER, the Default Button will not respond to ENTER presses
  • 除非對話方塊內容包含可設定焦點的 UI,否則按鈕在開啟對話方塊時都會自動取得焦點The button will receive focus automatically when the Dialog is opened unless the dialog's content contains focusable UI

使用 ContentDialog.DefaultButton 屬性來表示預設按鈕。Use the ContentDialog.DefaultButton property to indicate the default button. 預設不會設定任何預設按鈕。By default, no default button is set.

包含預設按鈕的三按鈕對話方塊

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();
}

確認對話方塊 (確定/取消)Confirmation dialogs (OK/Cancel)

確認對話方塊可讓使用者確認要執行的動作。A confirmation dialog gives users the chance to confirm that they want to perform an action. 使用者可以確認動作或選擇取消。They can affirm the action, or choose to cancel. 典型的確認對話方塊有兩個按鈕︰確認 (確定) 按鈕和取消按鈕。A typical confirmation dialog has two buttons: an affirmation ("OK") button and a cancel button.

  • 一般而言,確認按鈕應放在左邊 (主要按鈕),取消按鈕 (次要按鈕) 應放在右邊。In general, the affirmation button should be on the left (the primary button) and the cancel button (the secondary button) should be on the right.

    An OK/cancel dialog
  • 如一般建議一節所述,將按鈕與可識別針對主要指示或內容做出明確回應的文字搭配使用。As noted in the general recommendations section, use buttons with text that identifies specific responses to the main instruction or content.

某些平台將確認按鈕放在右邊,而非左邊。Some platforms put the affirmation button on the right instead of the left. 那麼,為什麼建議將它放在左邊?So why do we recommend putting it on the left? 如果您假設大部分使用者習慣使用右手,而且是以右手拿手機,那麼確認按鈕位於左邊時實際上會更好按,因為它更有可能在使用者的拇指弧形內。按鈕位於螢幕右邊時,使用者必須將其拇指向內扣入到不太舒適的姿勢。If you assume that the majority of users are right-handed and they hold their phone with that hand, it's actually more comfortable to press the affirmation button when it's on the left, because the button is more likely to be within the user's thumb-arc. Buttons on the right-side of the screen require the user to pull their thumb inward into a less-comfortable position.

ContentDialog AppWindow 或 Xaml IslandsContentDialog in AppWindow or Xaml Islands

注意:這一節僅適用於目標為 Windows 10 版本 1903 或更新版本的應用程式。NOTE: This section applies only to apps that target Windows 10, version 1903 or later. AppWindow 和 XAML Islands 不適用於舊版。AppWindow and XAML Islands are not available in earlier versions. 如需版本設定的詳細資訊,請參閱版本調適型應用程式For more info about versioning, see Version adaptive apps.

根據預設,內容對話方塊顯示強制相對於根目錄 ApplicationViewBy default, content dialogs display modally relative to the root ApplicationView. 當您使用 AppWindowXAML Island 內的 ContentDialog 時,您需要在對話方塊上將 XamlRoot 手動設為 XAML 主機的根目錄。When you use ContentDialog inside of either an AppWindow or a XAML Island, you need to manually set the XamlRoot on the dialog to the root of the XAML host.

若要這麼做,請將 ContentDialog 的 XamlRoot 屬性設定為與 AppWindow 或 XAML Island 中現有元素相同的 XamlRoot,如下所示。To do so, set the ContentDialog's XamlRoot property to the same XamlRoot as an element already in the AppWindow or XAML Island, as shown here.

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。There can only be one ContentDialog open per thread at a time. 嘗試開啟兩個 ContentDialogs 會擲回例外狀況,即使它們嘗試在不同的 AppWindows 中開啟。Attempting to open two ContentDialogs will throw an exception, even if they are attempting to open in separate AppWindows.

取得範例程式碼Get the sample code