飛出視窗Flyouts

飛出視窗是一個會消失關閉的容器,可顯示任意 UI 作為其內容。A flyout is a light dismiss container that can show arbitrary UI as its content. 飛出視窗可包含其他飛出視窗或操作功能表,以建立巢狀體驗。Flyouts can contain other flyouts or context menus to create a nested experience.

巢狀內嵌於飛出視窗內的操作功能表

取得 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: Flyout 類別Platform APIs: Flyout class

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

  • 不要使用飛出視窗來取代工具提示操作功能表Don't use a flyout instead of tooltip or context menu. 使用工具提示來顯示會在特定時間之後隱藏的簡短說明。Use a tooltip to show a short description that hides after a specified time. 使用操作功能表來執行與 UI 元素相關聯的內容相關動作,例如複製和貼上。Use a context menu for contextual actions related to a UI element, such as copy and paste.

如需使用飛出視窗和使用對話方塊 (類似的控制項) 之時機的建議,請參閱對話方塊和飛出視窗For recommendations on when to use a flyout vs. when to use a dialog (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.

如何建立飛出視窗How to create a flyout

飛出視窗會附加至特定的控制項。Flyouts are attached to specific controls. 您可以使用 Placement 屬性來指定飛出視窗的顯示位置︰Top、Left、Bottom、Right 或 Full。You can use the Placement property to specify where a flyout appears: Top, Left, Bottom, Right, or Full. 如果您選取「Full」位置模式,App 會延展飛出視窗,並將它置於 App 視窗的中央。If you select the Full placement mode, the app stretches the flyout and centers it inside the app window. 有些控制項 (例如,Button) 會提供可用來與飛出視窗或操作功能表產生關聯的 Flyout 屬性。Some controls, such as Button, provide a Flyout property that you can use to associate a flyout or context menu.

這個範例會建立簡單的飛出視窗,並在按下按鈕時顯示一些文字。This example creates a simple flyout that displays some text when the button is pressed.

<Button Content="Click me">
  <Button.Flyout>
     <Flyout>
        <TextBlock Text="This is a flyout!"/>
     </Flyout>
  </Button.Flyout>
</Button>

如果控制項沒有 flyout 屬性,您可以改為使用 FlyoutBase.AttachedFlyout 附加屬性。If the control doesn't have a flyout property, you can use the FlyoutBase.AttachedFlyout attached property instead. 當您這樣做時,也需要呼叫 FlyoutBase.ShowAttachedFlyout 方法以顯示飛出視窗。When you do this, you also need to call the FlyoutBase.ShowAttachedFlyout method to show the flyout.

這個範例會將簡單的飛出視窗新增至影像。This example adds a simple flyout to an image. 當使用者點選影像時,App 會顯示飛出視窗。When the user taps the image, the app shows the flyout.

<Image Source="Assets/cliff.jpg" Width="50" Height="50"
  Margin="10" Tapped="Image_Tapped">
  <FlyoutBase.AttachedFlyout>
    <Flyout>
      <TextBlock Text="This is some text in a flyout."  />
    </Flyout>
  </FlyoutBase.AttachedFlyout>
</Image>
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
    FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}

先前的範例會以內嵌方式定義飛出視窗。The previous examples defined their flyouts inline. 您也可以將飛出視窗定義為靜態資源,然後和多個元素搭配使用。You can also define a flyout as a static resource and then use it with multiple elements. 這個範例會建立更複雜的飛出視窗,並會在點選影像縮圖時顯示該影像的大尺寸版本。This example creates a more complicated flyout that displays a larger version of an image when its thumbnail is tapped.

<!-- Declare the shared flyout as a resource. -->
<Page.Resources>
    <Flyout x:Key="ImagePreviewFlyout" Placement="Right">
        <!-- The flyout's DataContext must be the Image Source
             of the image the flyout is attached to. -->
        <Image Source="{Binding Path=Source}"
            MaxHeight="400" MaxWidth="400" Stretch="Uniform"/>
    </Flyout>
</Page.Resources>
<!-- Assign the flyout to each element that shares it. -->
<StackPanel>
    <Image Source="Assets/cliff.jpg" Width="50" Height="50"
           Margin="10" Tapped="Image_Tapped"
           FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
           DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
    <Image Source="Assets/grapes.jpg" Width="50" Height="50"
           Margin="10" Tapped="Image_Tapped"
           FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
           DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
    <Image Source="Assets/rainier.jpg" Width="50" Height="50"
           Margin="10" Tapped="Image_Tapped"
           FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
           DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
</StackPanel>
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
    FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}

設定飛出視窗樣式Style a flyout

若要設定飛出視窗的樣式,請修改其 FlyoutPresenterStyleTo style a Flyout, modify its FlyoutPresenterStyle. 這個範例會顯示一段換行的文字,並使文字區塊可供螢幕助讀程式存取。This example shows a paragraph of wrapping text and makes the text block accessible to a screen reader.

包含換行文字的協助工具飛出視窗

<Flyout>
  <Flyout.FlyoutPresenterStyle>
    <Style TargetType="FlyoutPresenter">
      <Setter Property="ScrollViewer.HorizontalScrollMode"
          Value="Disabled"/>
      <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
      <Setter Property="IsTabStop" Value="True"/>
      <Setter Property="TabNavigation" Value="Cycle"/>
    </Style>
  </Flyout.FlyoutPresenterStyle>
  <TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."/>
</Flyout>

設定 10 英呎體驗的飛出視窗樣式Styling flyouts for 10-foot experiences

像飛出視窗這樣的消失關閉控制項會將鍵盤和遊戲台焦點圈限在暫時性 UI 內,直到控制項關閉為止。Light dismiss controls like flyout trap keyboard and gamepad focus inside their transient UI until dismissed. 若要提供此行為的視覺提示,Xbox 上的消失關閉控制項將會繪製重疊,以使超出範圍 UI 的對比度和可見度變暗。To provide a visual cue for this behavior, light dismiss controls on Xbox draw an overlay that dims the contrast and visibility of out of scope UI. 此行為可以使用 LightDismissOverlayMode 屬性進行修改。This behavior can be modified with the LightDismissOverlayMode property. 根據預設,飛出視窗將會在 Xbox 上繪製消失關閉重疊,但不會在其他裝置系列上繪製,不過應用程式可以選擇將重疊強制為一律為 On 或一律為 OffBy default, flyouts will draw the light dismiss overlay on Xbox but not other device families, but apps can choose to force the overlay to be always On or always Off.

包含變暗重疊的飛出視窗

<MenuFlyout LightDismissOverlayMode="On">

消失關閉行為Light dismiss behavior

飛出視窗可以使用快速消失關閉動作來關閉,動作包括Flyouts can be closed with a quick light dismiss action, including

  • 點選飛出視窗外部Tap outside the flyout
  • 按下 Esc 鍵盤按鍵Press the Escape keyboard key
  • 按下硬體或軟體系統 [上一頁] 按鈕Press the hardware or software system Back button
  • 按下遊戲台 B 按鈕Press the gamepad B button

以點選來關閉時,這個手勢通常會沒入而無法傳遞至下面的 UI。When dismissing with a tap, this gesture is typically absorbed and not passed on to the UI underneath. 舉例說,如果已開啟的飛出視窗後面有可見的按鈕,使用者的第一個點選動作會關閉飛出視窗,但不會啟動此按鈕。For example, if there's a button visible behind an open flyout, the user's first tap dismisses the flyout but does not activate this button. 按下按鈕需要第二次點選。Pressing the button requires a second tap.

您可以指定按鈕作為飛出視窗的輸入傳遞元素,來變更此行為。You can change this behavior by designating the button as an input pass-through element for the flyout. 飛出視窗將會因為上述消失關閉動作而關閉,還會將點選事件傳遞至其所指定的 OverlayInputPassThroughElementThe flyout will close as a result of the light dismiss actions described above and will also pass the tap event to its designated OverlayInputPassThroughElement. 請考慮採用此行為,在功能類似的項目上加速使用者互動。Consider adopting this behavior to speed up user interactions on functionally similar items. 如果您的應用程式有我的最愛集合,而且集合中的每個項目都包含附加飛出視窗時,您可以合理預料使用者可能會希望與接連多個飛出視窗進行互動。If your app has a favorites collection and each item in the collection includes an attached flyout, it's reasonable to expect that users may want to interact with multiple flyouts in rapid succession.

[!NOTE] 請小心,不要指定會產生破壞性動作的重疊輸入傳遞元素。Be careful not to designate an overlay input pass-through element which results in a destructive action. 使用者已經習慣於不會啟用主要 UI 的慎重消失關閉動作。Users have become habituated to discreet light dismiss actions which do not activate primary UI. 不應讓 [關閉]、[刪除] 或類似具破壞性的按鈕在消失關閉時啟動,以免發生非預期和破壞性的行為。Close, Delete or similarly destructive buttons should not activate on light dismiss to avoid unexpected and disruptive behavior.

在下列範例中,FavoritesBar 中所有三個按鈕都會在第一次點選時啟動。In the following example, all three buttons inside FavoritesBar will be activated on the first tap.

<Page>
    <Page.Resources>
        <Flyout x:Name="TravelFlyout" x:Key="TravelFlyout"
                OverlayInputPassThroughElement="{x:Bind FavoritesBar}">
            <StackPanel>
                <HyperlinkButton Content="Washington Trails Association"/>
                <HyperlinkButton Content="Washington Cascades - Go Northwest! A Travel Guide"/>
            </StackPanel>
        </Flyout>
    </Page.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel x:Name="FavoritesBar" Orientation="Horizontal">
            <HyperlinkButton x:Name="PageLinkBtn">Bing</HyperlinkButton>
            <Button x:Name="Folder1" Content="Travel" Flyout="{StaticResource TravelFlyout}"/>
            <Button x:Name="Folder2" Content="Entertainment" Click="Folder2_Click"/>
        </StackPanel>
        <ScrollViewer Grid.Row="1">
            <WebView x:Name="WebContent"/>
        </ScrollViewer>
    </Grid>
</Page>
private void Folder2_Click(object sender, RoutedEventArgs e)
{
     Flyout flyout = new Flyout();
     flyout.OverlayInputPassThroughElement = FavoritesBar;
     ...
     flyout.ShowAt(sender as FrameworkElement);
{

取得範例程式碼Get the sample code