Поделиться через


Flyouts

Всплывающее окно — это легко закрываемый контейнер, который отображает в качестве содержимого любой интерфейс. Всплывающие элементы могут содержать другие всплывающие элементы или контекстные меню, создавая вложенное взаимодействие.

Это правильный контроль?

  • Не используйте всплывающий элемент вместо подсказки или контекстного меню. Используйте подсказку, чтобы отобразить короткое описание, которое скрывается после указанного времени. Используйте контекстное меню для контекстных действий, связанных с элементом пользовательского интерфейса, например копирование и вставка.

Рекомендации о том, когда лучше использовать всплывающие элементы, а когда — диалоговые окна (схожие элементы управления), приведены в статье Диалоговые окна и всплывающие элементы.

Создайте всплывающее окно

Значок коллекции WinUI 3 Приложение WinUI 3 Gallery содержит интерактивные примеры элементов управления и функций WinUI. Получите приложение из Microsoft Store или просмотрите исходный код GitHub.

Всплывающие элементы присоединяются к определенным элементам управления. Свойство Размещение можно использовать для указания расположения всплывающего элемента: сверху, слева, внизу, справа или на полный экран. Если выбрать режим полного размещения, приложение растянут всплывающее окно и центрирует его в окне приложения. Некоторые элементы управления, например Button, содержат свойство Flyout, которое можно использовать для привязки всплывающего элемента или контекстного меню.

В этом примере создается простой всплывающий элемент, отображающий некоторый текст при нажатии кнопки.

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

Если элемент управления не имеет свойства всплывающего окна, можно вместо этого использовать присоединённое свойство FlyoutBase.AttachedFlyout. При этом также необходимо вызвать метод FlyoutBase.ShowAttachedFlyout , чтобы отобразить всплывающее меню.

В этом примере к изображению добавляется простой всплывающий элемент. Когда пользователь нажимает изображение, приложение отображает всплывающее меню.

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

В предыдущих примерах определены встроенные всплывающие элементы. Вы также можете определить всплывающий элемент как статический ресурс, а затем использовать его с несколькими элементами. В этом примере создается более сложное всплывающее окно, которое отображает увеличенную версию изображения при нажатии на его миниатюру.

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

Оформление всплывающего меню

Чтобы стилизовать всплывающее окно, измените его FlyoutPresenterStyle. В этом примере показан абзац обтекания текста и обеспечивается доступность блока текста для средств чтения с экрана.

Доступный всплывающий элемент с переносимым текстом

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

Настройка стиля всплывающих элементов для интерфейсов на больших экранах

Легкие элементы управления, такие как всплывающие окна, удерживают фокус клавиатуры и геймпада в своем временном пользовательском интерфейсе, пока они не закрыты. Чтобы предоставить визуальный сигнал для этого поведения, элементы управления с легким отклонением на Xbox добавляют наложение, которое уменьшает контрастность и видимость за пределами области пользовательского интерфейса. Это поведение можно изменить с помощью свойства LightDismissOverlayMode. По умолчанию всплывающие элементы будут отображать легкое наложение для закрытия на Xbox, но не на других семействах устройств. Однако приложения могут принудительно устанавливать наложение всегда в состояние On или Off.

Всплывающий элемент с затемняющим наложением

<MenuFlyout LightDismissOverlayMode="On">

Поведение с исчезновением

Всплывающие элементы можно закрыть с помощью быстрого легкого действия для закрытия.

  • Коснитесь области за пределами всплывающего окна.
  • Нажмите клавишу Escape на клавиатуре.
  • Нажмите аппаратную или программную системную кнопку "Назад".
  • Нажмите кнопку геймпада "B".

При отклонении касанием этот жест обычно поглощается и не передается далее пользовательскому интерфейсу под элементом. Например, если за открытым всплывающим элементом отображается кнопка, первое касание приведет к закрытию всплывающего элемента, но кнопка при этом не будет активирована. Для нажатия кнопки нужно второе касание.

Вы можете изменить это поведение, назначив кнопку в качестве элемента передачи ввода для всплывающего окна. Всплывающий элемент закроется при выполнении действий скрытия, описанных выше, и передаст событие нажатия назначенному элементу OverlayInputPassThroughElement. Такое поведение рекомендуется использовать для ускорения взаимодействия пользователей с функционально схожими элементами. Если ваше приложение имеет коллекцию избранного и каждый элемент в коллекции содержит присоединенный всплывающий элемент, логично предположить, что пользователям может потребоваться последовательно взаимодействовать с несколькими всплывающими элементами.

Замечание

Будьте осторожны, чтобы не назначить элемент ввода, проходящий через наложение, который приведет к деструктивному действию. Пользователи привыкли к ненавязчивым действиям с легким отверганием, которые не активируют основной пользовательский интерфейс. Закрыть, удалить или аналогично разрушительные кнопки не должны активироваться при отклонении света, чтобы избежать непредвиденного и разрушительного поведения.

В следующем примере будут активированы все три кнопки внутри FavoritesBar при первом касании.

<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);
{