다음을 통해 공유


Flyouts

플라이아웃은 쉽게 닫을 수 있는 컨테이너로, 임의의 사용자 인터페이스를 내용으로 표시할 수 있습니다. 플라이아웃에 중첩된 환경을 만들기 위한 다른 플라이아웃이나 상황에 맞는 메뉴가 포함될 수 있습니다.

이것이 올바른 컨트롤인가요?

  • 플라이아웃을 툴팁 또는 컨텍스트 메뉴대신 사용하지 마세요. 툴팁을 사용하여 지정된 시간 후에 사라지는 간단한 설명을 표시합니다. 복사 및 붙여넣기와 같은 UI 요소와 관련된 상황에 맞는 작업을 위해 컨텍스트 메뉴를 사용합니다.

플라이아웃을 사용해야 할 경우와 대화 상자(비슷한 컨트롤)를 사용해야 할 경우에 대한 권장 사항을 보려면 대화 상자 및 플라이아웃을 참조하세요.

플라이아웃 만들기

WinUI 3 갤러리 아이콘 WinUI 3 갤러리 앱에는 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>

10피트 환경을 위한 플라이아웃 스타일 지정

간편 해제 컨트롤(예: 플라이아웃)은 해제될 때까지 일시적 UI 내에서 키보드 및 게임패드 포커스를 가둡니다. 이 동작에 대한 시각적 신호를 제공하기 위해 Xbox 라이트 해제 컨트롤은 범위를 벗어난 UI의 대비와 가시성을 흐리게 하는 오버레이를 그립니다. 이 동작은 LightDismissOverlayMode 속성으로 수정할 수 있습니다. 기본적으로 플라이아웃은 Xbox에서는 가벼운 해제 오버레이를 표시하지만, 다른 디바이스 패밀리에서는 표시하지 않습니다. 그러나 앱은 오버레이를 항상 On 또는 항상 Off로 설정할 수 있습니다.

배경을 어둡게 만드는 오버레이가 포함된 플라이아웃

<MenuFlyout LightDismissOverlayMode="On">

가벼운 해제 동작

다음을 포함한 빠른 해제 동작으로 플라이아웃을 닫을 수 있습니다.

  • 플라이아웃 밖을 누르세요
  • Esc 키보드 키 누르기
  • 하드웨어 또는 소프트웨어 시스템의 뒤로 단추 누르기
  • 게임 패드 B 단추 누르기

탭으로 해제 시 이 제스처는 대개 포함되고 UI 아래에 전달되지 않습니다. 예를 들어, 열려 있는 플라이아웃 뒤에 단추가 표시된 경우 사용자의 첫 번째 탭으로 플라이아웃이 해제되지만 이 단추가 활성화되지는 않습니다. 단추를 누르려면 두 번째 탭이 필요합니다.

플라이아웃에 대한 입력 통과 요소로 단추를 지정하여 이 동작을 변경할 수 있습니다. 플라이아웃은 위에 설명된 '경미한 해제' 동작으로 인해 닫히고, 탭 이벤트를 지정된 OverlayInputPassThroughElement에 전달합니다. 이러한 동작을 채택하여 기능적으로 비슷한 항목에 대한 사용자 상호 작용 속도를 높일 수 있습니다. 앱에 즐겨찾기 컬렉션이 있고 컬렉션의 각 항목에 연결된 플라이아웃이 포함된 경우 사용자가 빠르게 여러 플라이아웃과 연달아 상호 작용할 것으로 예상할 수 있습니다.

비고

파괴적 작업을 유발하는 오버레이 입력 통과 요소를 지정하지 않도록 주의하세요. 사용자는 기본 UI를 활성화하지 않는 빠른 해제 작업에 익숙해졌습니다. 닫기, 삭제 또는 비슷하게 파괴적인 버튼은 예기치 않은 파괴적 동작을 피하기 위해 가벼운 닫힘에서 작동하지 않아야 합니다.

다음 예에서는 FavoritesBar 내의 3가지 단추 모두 첫 번째 탭에서 활성화됩니다.

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