Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Всплывающее окно отображает содержимое поверх остального интерфейса приложения. Класс Popup в пространстве имен Microsoft.UI.Xaml.Controls.Primitives — это контейнер общего назначения для размещения такого содержимого. У него нет визуального шаблона по умолчанию, поэтому вы предоставляете содержимое, его внешний вид и логику, которая открывает и закрывает его.
Popup — это базовый компонент низкого уровня. WinUI также предоставляет элементы управления для распространенных типов временных элементов интерфейса, таких как всплывающие элементы, диалоги, TeachingTip и подсказки. Эти элементы управления включают собственные стиль, расположение и поведение закрытия.
Это правильный контроль?
Не используйте Popup, если для вашего сценария подходит элемент управления более высокого уровня. Вместо этого используйте следующие элементы управления:
| Scenario | CTRL |
|---|---|
| Показывать сведения или получать ввод данных, связанных с элементом, в пользовательском интерфейсе, который закрывается при щелчке вне его. | Flyout |
| Показать список команд или параметров. | MenuFlyout |
| Задайте вопрос или покажите информацию, на которую пользователь должен ответить перед продолжением. | ContentDialog |
| Укажите новую или важную функцию с указанием конкретного элемента или без него. | Совет по обучению |
| Отображать краткое описание элемента при наведении указателя мыши на него или перемещении фокуса на него. | Подсказка |
Используйте Popup, когда вам нужно пользовательское содержимое, которое отображается поверх пользовательского интерфейса, и ни один из этих элементов управления не соответствует вашим потребностям. Например, вы можете использовать всплывающее окно в качестве оверлея, которое вы сами стилизуете и позиционируете.
Всплывающее окно не модальное, поэтому пользователь по-прежнему может взаимодействовать с пользовательским интерфейсом за ним. Если пользователь должен ответить перед продолжением, используйте ContentDialog.
Recommendations
- Добавьте содержимому всплывающего окна фон, границу и скруглённые углы, чтобы оно выделялось на фоне пользовательского интерфейса позади него. В примере Gallery WinUI 3 используются ресурсы
AcrylicBackgroundFillColorDefaultBrush,SurfaceStrokeColorDefaultBrushиOverlayCornerRadius. Дополнительные сведения см. в разделе Акриловый материал и ThemeShadow в всплывающих окнах. - Если вы не включите закрытие по щелчку вне окна, добавьте кнопку или другой элемент управления, закрывающий всплывающее окно.
- Делайте содержимое всплывающего окна кратким и сосредоточенным на одной задаче.
Создайте всплывающее окно
- Важные API: класс Popup, свойство IsOpen, свойство Child
![]()
Приложение WinUI 3 Gallery содержит интерактивные примеры элементов управления и функций WinUI. Получите приложение из Microsoft Store или просмотрите исходный код в GitHub.
Всплывающее окно содержит один элемент, который вы задали в качестве Child. Дочерний элемент обычно представляет собой панель или UserControl, который определяет содержимое всплывающего окна. Чтобы отобразить всплывающее окно, задайте для IsOpen значение true. Чтобы скрыть его, установите IsOpen в значение false.
Этот пример основан на образце WinUI 3 Gallery. Он объявляет всплывающее окно рядом с кнопкой, которая его открывает, и содержимое всплывающего окна содержит кнопку, которая закрывает всплывающее окно.
<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, завершается сбоем.
null элемента имеет значение XamlRoot до тех пор, пока элемент не будет добавлен в активное визуальное дерево, поэтому получайте значение из уже загруженного элемента, а не в конструкторе страницы.
Window В классе можно использоватьthis.Content.XamlRoot. Дополнительные сведения см. в разделе ContentDialog и Popup.
Note
Всплывающее окно, которое не находится в визуальном дереве, не изменяет положение при появлении сенсорной клавиатуры, поэтому клавиатура может перекрыть его. Если всплывающее окно содержит элементы управления вводом текста, например, TextBox, объявите всплывающее окно в XAML или добавьте его на панель в визуальном дереве.
Закрыть всплывающее окно щелчком вне его
По умолчанию всплывающее окно остается открытым до тех пор, пока ваш код не установит IsOpen в false. Установите для IsLightDismissEnabled значение true, чтобы закрыть всплывающее окно, когда пользователь щелкает или нажимает вне него или нажимает клавишу ESC. Это поведение называется закрытием по щелчку вне элемента.
По умолчанию область за пределами всплывающего окна с закрытием по щелчку вне окна не затемняется. Чтобы затемнить его, задайте для LightDismissOverlayMode значение On. Это свойство не имеет эффекта, если IsLightDismissEnabled имеет значение false.
<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с кнопкой, поэтому всплывающее окно отображается на 200 пикселей правее верхнего левого углаGrid. - Всплывающее окно, которое не имеет родительского элемента, например создаваемого в коде, смещается с левого верхнего угла корня XAML, который обычно является областью содержимого окна приложения.
Поместите всплывающее окно рядом с элементом
Чтобы отобразить всплывающее окно рядом с определенным элементом, задайте PlacementTarget этому элементу. Затем задайте для DesiredPlacement значение PopupPlacementMode, отличное от Auto, например Bottom или RightEdgeAlignedTop.
Когда откроется всплывающее окно, платформа позиционирует его относительно целевого элемента. Если всплывающее окно не помещается в предпочтительную позицию, фреймворк перемещает его на противоположную сторону целевого объекта.
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 App SDK версии 1.4, можно присвоить ShouldConstrainToRootBounds значение false, чтобы разрешить всплывающему окну выходить за пределы окна. Например, это можно сделать, если всплывающее окно больше небольшого окна.
Задайте ShouldConstrainToRootBounds перед первым открытием всплывающего окна. Вы не можете изменить его после открытия всплывающего окна.
<Popup x:Name="UnconstrainedPopup" ShouldConstrainToRootBounds="False">
<!-- Popup content -->
</Popup>
Анимировать всплывающее окно
Чтобы анимировать всплывающее содержимое при появлении, добавьте переход к коллекции ChildTransitions . PopupThemeTransition предоставляет анимацию для всплывающего пользовательского интерфейса, например содержимого подсказки, при его появлении.
<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. Дополнительные сведения см. в разделе Показать/скрыть всплывающее окно.
Реагировать при открытии или закрытии всплывающего окна
Событие Opened возникает, если для IsOpen задано значение true. Событие "Закрыто" возникает, если IsOpen задано значение false, в том числе при закрытии всплывающего окна по щелчку вне окна. Используйте Closed для действий, которые должны выполняться, независимо от того, как закрывается всплывающее окно. Например, пример коллекции WinUI 3 использует Closed для повторного включения параметра, отключаемого во время открытия всплывающего окна.
Оба события используют EventHandler<object>, поэтому обработчики принимают object отправителя и object аргумент события.
<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.";
}
Клавиатура, фокус и специальные возможности
- Если включено закрытие по щелчку вне окна, открытие всплывающего окна перемещает фокус в него, и закрытие всплывающего окна возвращает фокус к элементу, который был в фокусе до этого. Пользователь также может нажать клавишу ESC, чтобы закрыть всплывающее окно.
- Если отключение света не включено, всплывающее окно не перемещает фокус при открытии. Переместите фокус на элемент всплывающего окна после его открытия, включите кнопку "Закрыть", до которой пользователи клавиатуры могут добраться, и верните фокус к элементу, который открыл всплывающее окно, после его закрытия.
- Всплывающее окно не вызывает маршрутизируемые события, такие как
KeyDownиPointerPressed. Чтобы обработать эти события, подключите обработчики к дочернему элементу всплывающего окна. - Убедитесь, что каждый интерактивный элемент во всплывающем окне имеет доступное имя. Дополнительные сведения см. в разделе "Специальные возможности клавиатуры " и "Предоставление основных сведений о специальных возможностях".
Связанные статьи
Windows developer