Поведение при размещении контекстного меню
Элемент управления Popup отображает содержимое в отдельном окне, расположенном поверх приложения. Вы можете указать расположение Popup относительно элемента управления, указателя мыши или экрана с помощью свойств PlacementTarget, Placement, PlacementRectangle, HorizontalOffset и VerticalOffset. Вместе эти свойства позволяют гибко указывать положение Popup.
Примечание.
Классы ToolTip и ContextMenu также определяют эти пять свойств и ведут себя аналогичным образом.
Размещение всплывающего окна
Размещение Popup может быть задано относительно UIElement или всего экрана. В следующем примере показано создание четырех элементов управления Popup, располагаемых относительно к элемента UIElement, в данном случае это изображение. Все элементы управления Popup имеют свойство PlacementTarget со значением image1
, но у каждого Popup свойство размещения имеет иное значение.
<Canvas Width="200" Height="150">
<Image Name="image1"
Canvas.Left="75"
Source="Water_lilies.jpg" Height="200" Width="200"/>
<Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
Placement="Bottom">
<TextBlock FontSize="14" Background="LightGreen">Placement=Bottom</TextBlock>
</Popup>
<Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
Placement="Top">
<TextBlock FontSize="14" Background="LightGreen">Placement=Top</TextBlock>
</Popup>
<Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
Placement="Left">
<TextBlock FontSize="14" Background="LightGreen">Placement=Left</TextBlock>
</Popup>
<Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
Placement="Right">
<TextBlock FontSize="14" Background="LightGreen">Placement=Right</TextBlock>
</Popup>
</Canvas>
На следующем рисунке показаны элементы управления Popup и изображение:
В этом простом примере показано, как задать свойства PlacementTarget и Placement, но с помощью свойств PlacementRectangle, HorizontalOffsetи VerticalOffset можно еще лучше контролировать расположение Popup.
! [ПРИМЕЧАНИЕ] В зависимости от параметров Windows, связанных с рукой, всплывающее окно может быть выровнено по левому или правому краю при отображении вверху или нижнем углу. Предыдущее изображение демонстрирует выравнивание правой руки, которое помещает всплывающее окно слева.
Определение терминов: анатомия всплывающего окна
Следующие термины полезны для понимания того, как свойства PlacementTarget, Placement, PlacementRectangle, HorizontalOffsetи VerticalOffset связаны друг с другом и с Popup:
Целевой объект
Целевая область
Исходная точка
Точка выравнивания всплывающего окна
Эти термины удобно использовать для ссылки на различные аспекты Popup и связанные с ним элементы управления.
Целевой объект
Целевой объект является элементом, с которым связано Popup. Если свойство PlacementTarget задано, оно указывает целевой объект. Если параметр PlacementTarget не задан, а Popup имеет родительский объект, то такой родительский объект является целевым объектом. Если родительского объекта и значения PlacementTarget нет, то целевой объект отсутствует, а Popup располагается относительно экрана.
В следующем примере создается Popup, являющийся дочерним объектом для Canvas. В этом примере не задается свойство PlacementTarget в Popup. Значение по умолчанию для Placement — PlacementMode.Bottom, поэтому Popup отображается под Canvas.
<Canvas Margin="5" Background="Red" Width="200" Height="150" >
<Ellipse Canvas.Top="60" Canvas.Left="50"
Height="85" Width="60"
Fill="Black"/>
<Popup IsOpen="True" >
<TextBlock Background="LightBlue" FontSize="18">This is a Popup</TextBlock>
</Popup>
</Canvas>
На следующем рисунке показано, что Popup располагается относительно Canvas.
В следующем примере создается Popup, являющийся дочерним объектом для Canvas, но на этот раз для PlacementTarget задано значение ellipse1
, поэтому всплывающее окно отображается под Ellipse.
<Canvas Margin="5" Background="Red" Width="200" Height="150" >
<Ellipse Name="ellipse1"
Canvas.Top="60" Canvas.Left="50"
Height="85" Width="60"
Fill="Black"/>
<Popup IsOpen="True" PlacementTarget="{Binding ElementName=ellipse1}">
<TextBlock Background="LightBlue" FontSize="18">This is a Popup</TextBlock>
</Popup>
</Canvas>
На следующем рисунке показано, что Popup располагается относительно Ellipse.
Примечание.
Для ToolTip значением по умолчанию для Placement является Mouse. Для ContextMenu значением по умолчанию для Placement является MousePoint. Эти значения описаны дальше, в разделе "Совместная работа свойств".
Целевая область
Целевая область — это область на экране, относительно которой располагается Popup. В предыдущих примерах Popup выравнивается по границам целевого объекта, но в некоторых случаях Popup выравнивается по другим границам, даже если у Popup есть целевой объект. Если указано значение свойства PlacementRectangle, целевая область отличается от границ целевого объекта.
В следующем примере создаются два объекта Canvas, каждый из которых содержит Rectangle и Popup. В обоих случаях целевым объектом для Popup является Canvas. Для Popup в первом Canvas задано свойство PlacementRectangle, а для свойств X, Y, Width и Height заданы значения 50, 50, 50 и 100 соответственно. Для Popup во втором Canvas свойство PlacementRectangle не задано. В результате первый Popup располагается под PlacementRectangle, а второй Popup — под Canvas. Каждый Canvas также содержит Rectangle с теми же границами, что и у PlacementRectangle для первого Popup. Обратите внимание, что PlacementRectangle не создает видимый элемент в приложении; в примере Rectangle создается для представления PlacementRectangle.
<StackPanel Orientation="Horizontal" Margin="50,50,0,0">
<Canvas Width="200" Height="200" Background="Red">
<Rectangle Canvas.Top="50" Canvas.Left="50"
Width="50" Height="100"
Stroke="White" StrokeThickness="3"/>
<Popup IsOpen="True" PlacementRectangle="50,50,50,100">
<TextBlock FontSize="14" Background="Yellow"
Width="140" TextWrapping="Wrap">
This is a popup with a PlacementRectangle.
</TextBlock>
</Popup>
</Canvas>
<Canvas Width="200" Height="200" Background="Red" Margin="30,0,0,0">
<Rectangle Canvas.Top="50" Canvas.Left="50"
Width="50" Height="100"
Stroke="White" StrokeThickness="3"/>
<Popup IsOpen="True">
<TextBlock FontSize="14" Background="Yellow"
Width="140" TextWrapping="Wrap">
This is a popup without a PlacementRectangle.
</TextBlock>
</Popup>
</Canvas>
</StackPanel>
На следующем рисунке показан результат примера, приведенного выше.
Исходная точка и точка выравнивания всплывающего окна
Исходная точка и точка выравнивания всплывающего окна являются опорными точками на целевой области и всплывающем окне соответственно, которые используются для позиционирования. Вы можете использовать свойства HorizontalOffset и VerticalOffset для смещения всплывающего окна от целевой области. HorizontalOffset и VerticalOffset располагаются относительно исходной точки и точки выравнивания всплывающего окна. Значение свойства Placement определяет местоположение исходной точки и точки выравнивания всплывающего окна.
В следующем примере создается Popup, а для свойств HorizontalOffset и VerticalOffset задается значение 20. Свойству Placement присвоено значение Bottom (по умолчанию), поэтому исходной точкой является левый нижний угол целевой области, а точкой выравнивания всплывающего окна — левый верхний угол Popup.
<Canvas Width="200" Height="200" Background="Yellow" Margin="20">
<Popup IsOpen="True" Placement="Bottom"
HorizontalOffset="20" VerticalOffset="20">
<TextBlock FontSize="14" Background="#42F3FD">
This is a popup.
</TextBlock>
</Popup>
</Canvas>
На следующем рисунке показан результат примера, приведенного выше.
Совместная работа свойств
Значения PlacementTarget, PlacementRectangle и Placement нужно рассматривать вместе для определения правильной целевой области, исходной точки и точки выравнивания всплывающего окна. Например, если значение Placement равно Mouse, целевой объект отсутствует, PlacementRectangle игнорируется, а целевой областью являются границы указателя мыши. С другой стороны, если значение Placement равно Bottom, PlacementTarget или родительский объект определяет целевой объект, а PlacementRectangle определяет целевую область.
В следующей таблице описаны целевой объект, целевая область, исходная точка и точка выравнивания всплывающего окна, а также указано, используются ли PlacementTarget и PlacementRectangle для каждого значения перечисления PlacementMode.
PlacementMode | Целевой объект | Целевая область | Исходная точка | Точка выравнивания всплывающего окна |
---|---|---|---|---|
Absolute | Неприменимо. PlacementTarget не учитывается. | Экран или PlacementRectangle, если он задан. PlacementRectangle задается относительно экрана. | Левый верхний угол целевой области. | Левый верхний угол Popup. |
AbsolutePoint | Неприменимо. PlacementTarget не учитывается. | Экран или PlacementRectangle, если он задан. PlacementRectangle задается относительно экрана. | Левый верхний угол целевой области. | Левый верхний угол Popup. |
Bottom | PlacementTarget или родительский объект. | Целевой объект или PlacementRectangle, если он задан. PlacementRectangle задается относительно целевого объекта. | Левый нижний угол целевой области. | Левый верхний угол Popup. |
Center | PlacementTarget или родительский объект. | Целевой объект или PlacementRectangle, если он задан. PlacementRectangle задается относительно целевого объекта. | Центр целевой области. | Центр Popup. |
Custom | PlacementTarget или родительский объект. | Целевой объект или PlacementRectangle, если он задан. PlacementRectangle задается относительно целевого объекта. | Определяется CustomPopupPlacementCallback. | Определяется CustomPopupPlacementCallback. |
Left | PlacementTarget или родительский объект. | Целевой объект или PlacementRectangle, если он задан. PlacementRectangle задается относительно целевого объекта. | Левый верхний угол целевой области. | Правый верхний угол Popup. |
Mouse | Неприменимо. PlacementTarget не учитывается. | Границы указателя мыши. PlacementRectangle не учитывается. | Левый нижний угол целевой области. | Левый верхний угол Popup. |
MousePoint | Неприменимо. PlacementTarget не учитывается. | Границы указателя мыши. PlacementRectangle не учитывается. | Левый верхний угол целевой области. | Левый верхний угол Popup. |
Relative | PlacementTarget или родительский объект. | Целевой объект или PlacementRectangle, если он задан. PlacementRectangle задается относительно целевого объекта. | Левый верхний угол целевой области. | Левый верхний угол Popup. |
RelativePoint | PlacementTarget или родительский объект. | Целевой объект или PlacementRectangle, если он задан. PlacementRectangle задается относительно целевого объекта. | Левый верхний угол целевой области. | Левый верхний угол Popup. |
Right | PlacementTarget или родительский объект. | Целевой объект или PlacementRectangle, если он задан. PlacementRectangle задается относительно целевого объекта. | Правый верхний угол целевой области. | Левый верхний угол Popup. |
Top | PlacementTarget или родительский объект. | Целевой объект или PlacementRectangle, если он задан. PlacementRectangle задается относительно целевого объекта. | Левый верхний угол целевой области. | Левый нижний угол Popup. |
На следующих рисунках показаны Popup, целевая область, исходная точка и точка выравнивания всплывающего окна для каждого значения PlacementMode. На каждом рисунке целевая область закрашена желтым, а Popup — голубым цветом.
Когда всплывающее окно достигает края экрана
По соображениям безопасности Popup не может быть скрыто за краем экрана. При достижении Popup края экрана происходит одно из следующих трех событий:
Всплывающее окно располагается вдоль края экрана, который мог бы скрыть Popup.
Всплывающее окно использует другую точку выравнивания.
Всплывающее окно использует другую исходную точку и точку выравнивания.
Эти параметры будут описаны далее в данном разделе.
Поведение Popup при достижении края экрана зависит от значения свойства Placement и от того, с каким краем экрана сталкивается всплывающее окно. Следующая таблица содержит сводные сведения о поведении, имеющем место, когда Popup достигает границы экрана, для каждого значения PlacementMode.
PlacementMode | Верхний край | Нижний край | Левый край | Правый край |
---|---|---|---|---|
Absolute | Выравнивание по верхнему краю. | Выравнивание по нижнему краю. | Выравнивание по левому краю. | Выравнивание по правому краю. |
AbsolutePoint | Выравнивание по верхнему краю. | Точка выравнивания всплывающего окна переходит в нижний левый угол Popup. | Выравнивание по левому краю. | Точка выравнивания всплывающего окна переходит в верхний правый угол Popup. |
Bottom | Выравнивание по верхнему краю. | Исходная точка переходит в левый верхний угол целевой области, а точка выравнивания всплывающего окна переходит в левый нижний угол Popup. | Выравнивание по левому краю. | Выравнивание по правому краю. |
Center | Выравнивание по верхнему краю. | Выравнивание по нижнему краю. | Выравнивание по левому краю. | Выравнивание по правому краю. |
Left | Выравнивание по верхнему краю. | Выравнивание по нижнему краю. | Исходная точка переходит в правый верхний угол целевой области, а точка выравнивания всплывающего окна переходит в левый верхний угол Popup. | Выравнивание по правому краю. |
Mouse | Выравнивание по верхнему краю. | Исходная точка переходит в левый верхний угол целевой области (границы указателя мыши), а точка выравнивания всплывающего окна переходит в левый нижний угол Popup. | Выравнивание по левому краю. | Выравнивание по правому краю. |
MousePoint | Выравнивание по верхнему краю. | Точка выравнивания всплывающего окна переходит в нижний левый угол Popup. | Выравнивание по левому краю. | Точка выравнивания всплывающего окна переходит в верхний правый угол всплывающего окна. |
Relative | Выравнивание по верхнему краю. | Выравнивание по нижнему краю. | Выравнивание по левому краю. | Выравнивание по правому краю. |
RelativePoint | Выравнивание по верхнему краю. | Точка выравнивания всплывающего окна переходит в нижний левый угол Popup. | Выравнивание по левому краю. | Точка выравнивания всплывающего окна переходит в верхний правый угол всплывающего окна. |
Right | Выравнивание по верхнему краю. | Выравнивание по нижнему краю. | Выравнивание по левому краю. | Исходная точка переходит в левый верхний угол целевой области, а точка выравнивания всплывающего окна переходит в правый верхний угол Popup. |
Top | Исходная точка переходит в левый нижний угол целевой области, а точка выравнивания всплывающего окна переходит в левый верхний угол Popup. Фактически, это аналогично ситуации, когда Placement имеет значение Bottom. | Выравнивание по нижнему краю. | Выравнивание по левому краю. | Выравнивание по правому краю. |
Выравнивание по краю экрана
Объект Popup может выровняться по краю экрана путем изменения расположения, таким образом все всплывающее окно Popup будет отображаться на экране. В этом случае расстояние между исходной точкой и точкой выравнивания всплывающего окна может отличаться от значений HorizontalOffset и VerticalOffset. Если Placement имеет значение Absolute, Center или Relative, Popup выравнивается по всем границам экрана. Например, предположим, что у Popup для Placement задано значение Relative, а для VerticalOffset — значение 100. Если нижний край экрана полностью или частично скрывает Popup, Popup располагается вдоль нижнего края экрана, а расстояние по вертикали между исходной точкой и точкой выравнивания всплывающего окна составляет меньше 100. Эта ситуация представлена на рисунке ниже.
Изменение точки выравнивания всплывающего окна
Если Placement имеет значение AbsolutePoint, RelativePoint или MousePoint, точка выравнивания всплывающего окна изменяется, когда всплывающее окно достигает нижнего или правого края экрана.
На следующем рисунке показано, что, если нижний край экрана полностью или частично скрывает Popup, точка выравнивания всплывающего окна находится в левом нижнем углу Popup.
На следующем рисунке показано, что, если правый край экрана скрывает Popup, точка выравнивания всплывающего окна находится в правом верхнем углу Popup.
Если Popup достигает нижнего и правого краев экрана, точка выравнивания всплывающего окна находится в правом нижнем углу Popup.
Изменение положения исходной точки и точки выравнивания всплывающего окна
Если Placement имеет значение Bottom, Left, Mouse, Right или Top, исходная точка и точка выравнивания всплывающего окна изменяются при достижении определенного края экрана. Край экрана, который вызывает изменение положения, зависит от значения PlacementMode.
На следующем рисунке показано, что если Placement имеет значение Bottom и Popup достигает нижнего края экрана, то исходной точкой является левый верхний угол целевой области, а точкой выравнивания всплывающего окна — левый нижний угол Popup.
На следующем рисунке показано, что если Placement имеет значение Left и Popup достигает левого края экрана, то исходной точкой является правый верхний угол целевой области, а точкой выравнивания всплывающего окна — левый верхний угол Popup.
На следующем рисунке показано, что если Placement имеет значение Right и Popup достигает правого края экрана, то исходной точкой является левый верхний угол целевой области, а точкой выравнивания всплывающего окна — правый верхний угол Popup.
На следующем рисунке показано, что если Placement имеет значение Top и Popup достигает верхнего края экрана, то исходной точкой является левый нижний угол целевой области, а точкой выравнивания всплывающего окна — левый верхний угол Popup.
На следующем рисунке показано, что если Placement имеет значение Mouse и Popup достигает нижнего края экрана, то исходной точкой является левый верхний угол целевой области (границы указателя мыши), а точкой выравнивания всплывающего окна — левый нижний угол Popup.
Настройка размещения контекстного меню
Вы можете настроить исходную точку и точку выравнивания всплывающего окна, задав для свойства Placement значение Custom. Затем определите делегат CustomPopupPlacementCallback, который возвращает набор возможных точек размещения и основные оси (в порядке предпочтения) для Popup. Выбирается точка, в которой отображается наибольшая часть Popup. Расположение Popup автоматически корректируется, если граница экрана скрывает Popup. См. пример в разделе Указание пользовательского расположения контекстного меню.
См. также
.NET Desktop feedback