팝업은 앱의 다른 UI 위에 콘텐츠를 표시합니다.
네임스페이스의 Microsoft.UI.Xaml.Controls.Primitives 클래스는 해당 콘텐츠에 대한 범용 컨테이너입니다. 기본 시각적 템플릿이 없으므로 콘텐츠, 모양 및 이를 열고 닫는 논리를 제공합니다.
Popup은 하위 수준의 기본 구성 요소입니다. 또한 WinUI는 플라이아웃, 대화 상자, 교육 팁 및 도구 설명과 같은 일반적인 종류의 임시 UI에 대한 컨트롤을 제공합니다. 이러한 컨트롤에는 고유한 스타일 지정, 배치 및 닫기 동작이 포함됩니다.
이것이 올바른 컨트롤인가요?
시나리오에 더 적합한 상위 수준 컨트롤이 있으면 Popup를 사용하지 마세요. 대신 다음 컨트롤을 사용하세요:
| Scenario | 컨트롤 |
|---|---|
| 사용자가 UI 바깥을 클릭하면 닫히는 UI에서 항목과 관련된 정보를 표시하거나 입력을 수집합니다. | 플라이아웃 |
| 명령 또는 옵션 목록을 표시합니다. | MenuFlyout |
| 질문을 하거나 사용자가 계속하기 전에 응답해야 하는 정보를 표시합니다. | ContentDialog |
| 특정 요소를 대상으로 지정하거나 지정하지 않고 새 기능이나 중요한 기능을 강조 표시합니다. | TeachingTip |
| 사용자가 요소를 마우스로 가리키거나 포커스를 이동할 때 요소에 대한 간단한 설명을 표시합니다. | 툴팁 |
UI 위에 떠 있는 사용자 지정 콘텐츠가 필요하고 이러한 컨트롤 중 어느 것도 요구 사항을 충족하지 않는 경우 Popup를 사용합니다. 예를 들어 직접 스타일을 지정하고 배치하는 오버레이에 팝업을 사용할 수 있습니다.
팝업은 모달이 아니므로 사용자는 여전히 그 뒤에 있는 UI와 상호 작용할 수 있습니다. 사용자가 계속하기 전에 응답해야 하는 경우 ContentDialog를 사용합니다.
Recommendations
- 팝업 콘텐츠에 배경, 테두리 및 둥근 모서리를 제공하여 그 뒤에 있는 UI에서 눈에 띄도록 합니다. WinUI 3 갤러리 샘플에서는
SurfaceStrokeColorDefaultBrush,OverlayCornerRadius및AcrylicBackgroundFillColorDefaultBrush리소스를 사용합니다. 자세한 내용은 아크릴 소재 및 팝업의 ThemeShadow를 참조하세요. - 바깥쪽 클릭 시 닫기를 사용하도록 설정하지 않으면 팝업을 닫는 단추 또는 다른 컨트롤을 포함하세요.
- 팝업 콘텐츠를 간략하게 유지하고 단일 작업에 집중합니다.
팝업 만들기
![]()
WinUI 3 갤러리 앱에는 WinUI 컨트롤 및 기능의 대화형 예제가 포함되어 있습니다. Microsoft Store에서 앱을 다운로드하거나 GitHub 소스 코드를 찾습니다.
팝업은 Child로 설정한 단일 요소를 호스트합니다. 자식은 일반적으로 패널 또는 팝업 콘텐츠를 정의하는 UserControl입니다. 팝업을 표시하려면 IsOpen을 true로 설정합니다. 숨기려면 false을(를) IsOpen(으)로 설정합니다.
이 예제는 WinUI 3 갤러리 샘플을 기반으로 합니다. 팝업을 여는 단추 옆에 팝업을 선언하고 팝업 콘텐츠에는 팝업을 닫는 단추가 포함됩니다.
<Grid HorizontalAlignment="Left" VerticalAlignment="Top">
<Button Content="Show popup" Click="ShowPopupClicked" />
<Popup x:Name="StandardPopup" HorizontalOffset="200" VerticalOffset="0">
<Grid MinWidth="240"
Padding="16"
Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource OverlayCornerRadius}">
<StackPanel Spacing="8">
<TextBlock FontSize="16" Text="Simple popup" />
<Button Content="Close" Click="ClosePopupClicked" />
</StackPanel>
</Grid>
</Popup>
</Grid>
// Opens the popup if it isn't already open.
private void ShowPopupClicked(object sender, RoutedEventArgs e)
{
if (!StandardPopup.IsOpen)
{
StandardPopup.IsOpen = true;
}
}
// Closes the popup when the user clicks the Close button inside it.
private void ClosePopupClicked(object sender, RoutedEventArgs e)
{
if (StandardPopup.IsOpen)
{
StandardPopup.IsOpen = false;
}
}
코드에서 팝업 만들기
시각적 트리에 추가하지 않고 코드에서 팝업을 만들 수도 있습니다. XAML에서 선언하거나 시각적 트리의 패널에 추가하는 팝업은 부모 요소에서 해당 XamlRoot 를 가져옵니다. 부모가 없는 팝업은 열리지 않으므로 열기 전에 해당 XamlRoot 속성을 설정해야 합니다.
private Popup? _popup;
private void ShowPopupFromCodeClicked(object sender, RoutedEventArgs e)
{
_popup ??= new Popup
{
// PopupContent is a UserControl in your app that defines the popup content.
Child = new PopupContent(),
IsLightDismissEnabled = true,
// Required because this popup isn't in the visual tree. Use the XamlRoot
// of an element that's already loaded, such as the button that was clicked.
XamlRoot = ((UIElement)sender).XamlRoot
};
_popup.IsOpen = true;
}
Important
WinUI 3에서는 부모 요소도 없고 XamlRoot도 없는 팝업을 열면 실패합니다. 요소의 XamlRoot은 요소가 라이브 시각적 트리에 추가될 때까지 null 상태이므로, 페이지 생성자가 아니라 이미 로드된 요소에서 값을 가져옵니다.
Window 클래스에서 this.Content.XamlRoot를 사용할 수 있습니다. 자세한 내용은 ContentDialog 및 팝업을 참조하세요.
Note
시각적 트리에 없는 팝업은 터치 키보드가 나타날 때 자체 위치를 변경하지 않으므로 키보드가 이를 가릴 수 있습니다. 팝업에 텍스트 입력 컨트롤(예: TextBox 같은)이 포함된 경우 XAML에서 팝업을 선언하거나 시각적 트리의 패널에 추가합니다.
라이트 디스미스를 사용하여 팝업 닫기
기본적으로 팝업은 코드가 IsOpen를 false로 설정할 때까지 열린 상태로 유지됩니다. 사용자가 팝업 바깥쪽을 클릭하거나 탭하거나 Esc 키를 누를 때 팝업을 닫으려면 IsLightDismissEnabled를 true로 설정합니다. 이 동작을 light dismiss라고합니다.
기본적으로 라이트 디스미스 팝업 외부 영역은 어둡게 되지 않습니다. 어둡게 하려면 LightDismissOverlayMode를 On로 설정합니다. 이 속성은 다음과 같은 경우에는 IsLightDismissEnabledfalse영향을 주지 않습니다.
<Popup x:Name="LightDismissPopup"
IsLightDismissEnabled="True"
LightDismissOverlayMode="On">
<Border Padding="16"
Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource OverlayCornerRadius}">
<TextBlock Text="Click outside this popup or press Esc to close it." />
</Border>
</Popup>
팝업 위치 지정
오프셋을 사용하거나 다른 요소를 기준으로 팝업을 배치할 수 있습니다.
오프셋 사용
HorizontalOffset 및 VerticalOffset 은 팝업의 위치를 픽셀 단위로 설정합니다. 오프셋이 측정되는 지점은 팝업에 부모가 있는지 여부에 따라 달라집니다.
- 시각적 트리의 팝업은 부모 레이아웃에서의 팝업 자체 위치로부터 오프셋됩니다. 예를 들어 세로
StackPanel에서 해당 위치는 팝업 앞에 오는 요소 아래에 있습니다. 첫 번째 예제에서 팝업은 단추와 단일 셀Grid을 공유하므로Grid의 왼쪽 위 모서리에서 오른쪽으로 200픽셀 떨어진 위치에 나타납니다. - 코드에서 만든 팝업과 같이 부모가 없는 팝업은 일반적으로 앱 창의 콘텐츠 영역인 XAML 루트의 왼쪽 위 모서리를 기준으로 오프셋됩니다.
요소 옆에 팝업을 배치합니다
특정 요소 옆에 팝업을 표시하려면 PlacementTarget을 해당 요소로 설정하세요. 그런 다음 DesiredPlacement를 RightEdgeAlignedTop가 아닌 PopupPlacementMode 값(예: Auto 또는 Bottom)으로 설정합니다.
팝업이 열리면 프레임워크는 대상 요소를 기준으로 배치합니다. 팝업이 선호 위치에 맞지 않으면 프레임워크가 팝업을 대상의 반대쪽으로 이동합니다.
HorizontalOffset 및 VerticalOffset는 계속 적용되며, 계산된 위치에서 팝업을 이동합니다.
ActualPlacement 는 팝업이 표시되는 위치를 보고합니다. ActualPlacementChanged 이벤트는 팝업이 열려 있는 동안 해당 값이 변경되면 발생합니다.
<StackPanel Spacing="8">
<Button x:Name="DetailsButton" Content="Show details" Click="ShowDetailsClicked" />
<TextBlock x:Name="PlacementStatus" />
<Popup x:Name="DetailsPopup"
PlacementTarget="{x:Bind DetailsButton}"
DesiredPlacement="BottomEdgeAlignedLeft"
IsLightDismissEnabled="True"
ActualPlacementChanged="DetailsPopup_ActualPlacementChanged">
<Border Padding="16"
Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource OverlayCornerRadius}">
<TextBlock Text="This popup appears below the button when there's room." />
</Border>
</Popup>
</StackPanel>
private void ShowDetailsClicked(object sender, RoutedEventArgs e)
{
DetailsPopup.IsOpen = true;
}
private void DetailsPopup_ActualPlacementChanged(object sender, object e)
{
// ActualPlacement differs from DesiredPlacement when the popup
// doesn't fit in the preferred position.
PlacementStatus.Text = $"Actual placement: {DetailsPopup.ActualPlacement}";
}
앱 창 외부에 팝업 표시
기본적으로 팝업은 일반적으로 앱 창의 콘텐츠 영역인 XAML 루트의 범위로 제한됩니다. Windows 앱 SDK 1.4부터 false를 로 설정하여 팝업이 창 너머로 확장되도록 할 수 있습니다. 예를 들어 팝업이 작은 창보다 큰 경우 이 작업을 수행할 수 있습니다.
팝업을 처음 열기 전에 ShouldConstrainToRootBounds을 설정합니다. 팝업이 열린 후에는 변경할 수 없습니다.
<Popup x:Name="UnconstrainedPopup" ShouldConstrainToRootBounds="False">
<!-- Popup content -->
</Popup>
팝업에 애니메이션 적용
팝업 콘텐츠가 나타날 때 애니메이션 효과를 주려면 ChildTransitions 컬렉션에 전환을 추가합니다. PopupThemeTransition 은 표시되는 대로 도구 설명과 유사한 콘텐츠와 같은 팝인 UI에 대한 애니메이션을 제공합니다.
<Popup x:Name="AnimatedPopup" IsLightDismissEnabled="True">
<Popup.ChildTransitions>
<TransitionCollection>
<PopupThemeTransition />
</TransitionCollection>
</Popup.ChildTransitions>
<Border Padding="16"
Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource OverlayCornerRadius}">
<TextBlock Text="This content animates when the popup opens." />
</Border>
</Popup>
대신 스토리보드에서 표시 및 숨기기 애니메이션을 제어하려면 PopInThemeAnimation 및 PopOutThemeAnimation을 사용합니다. 자세한 내용은 팝업 표시/숨기기를 참조하세요.
팝업이 열리거나 닫히면 응답하세요
true이(가) IsOpen(으)로 설정되면 Opened 이벤트가 발생합니다.
Closed 이벤트는 IsOpen이 false(으)로 설정될 때 발생하며, 여기에는 팝업이 light dismiss를 통해 닫히는 경우도 포함됩니다. 팝업이 어떤 방식으로 닫히든 발생해야 하는 작업에 Closed를 사용합니다. 예를 들어, WinUI 3 갤러리 샘플은 팝업이 열려 있는 동안 비활성화한 설정을 Closed를 사용하여 다시 사용하도록 설정합니다.
두 이벤트 모두 EventHandler<object>를 사용하므로 처리기는 object sender와 object event 인수를 받습니다.
<StackPanel Spacing="8">
<TextBlock x:Name="StatusText" />
<Popup x:Name="StatusPopup"
IsLightDismissEnabled="True"
Opened="StatusPopup_Opened"
Closed="StatusPopup_Closed">
<!-- Popup content -->
</Popup>
</StackPanel>
private void StatusPopup_Opened(object sender, object e)
{
StatusText.Text = "The popup is open.";
}
private void StatusPopup_Closed(object sender, object e)
{
// Closed occurs for every close, including light dismiss.
StatusText.Text = "The popup is closed.";
}
키보드, 포커스 및 접근성
- Light Dismiss를 사용하도록 설정하면 팝업을 열면 포커스가 팝업 내부로 이동하고 팝업을 닫으면 포커스가 이전에 포커스가 있었던 요소로 돌아갑니다. 사용자는 Esc 키를 눌러 팝업을 닫을 수도 있습니다.
- light dismiss를 사용하도록 설정하지 않으면 팝업이 열릴 때 포커스가 이동하지 않습니다. 포커스를 연 후 팝업의 요소로 이동하고, 키보드 사용자가 접근할 수 있는 닫기 단추를 포함하고, 닫은 후 팝업을 연 요소에 포커스를 반환합니다.
- 팝업은
KeyDown및PointerPressed와 같은 라우트된 이벤트를 발생시키지 않습니다. 이러한 이벤트를 처리하려면 대신 팝업의 자식 요소에 처리기를 연결하세요. - 팝업의 각 대화형 요소에 액세스 가능한 이름이 있는지 확인합니다. 자세한 내용은 키보드 접근성 및 기본 접근성 정보 노출을 참조하세요.
관련된 문서
Windows developer