Поведение при размещении контекстного меню

Элемент управления 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 и изображение:

Image with four popup controls

В этом простом примере показано, как задать свойства 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 control with no PlacementTarget

В следующем примере создается 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.

Popup positioned relative to an 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>

На следующем рисунке показан результат примера, приведенного выше.

Popup with and without PlacementRectangle

Исходная точка и точка выравнивания всплывающего окна

Исходная точка и точка выравнивания всплывающего окна являются опорными точками на целевой области и всплывающем окне соответственно, которые используются для позиционирования. Вы можете использовать свойства 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>

На следующем рисунке показан результат примера, приведенного выше.

Popup placement with target origin alignment point

Совместная работа свойств

Значения 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 with Absolute or AbsolutePoint placement

Popup with Bottom placement

Popup with Center placement

Popup with Left placement

Popup with Mouse placement

Popup with MousePoint placement

Popup with Relative or RelativePoint placement

Popup with Right placement

Popup with Top placement

Когда всплывающее окно достигает края экрана

По соображениям безопасности 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. Эта ситуация представлена на рисунке ниже.

Popup that aligns to edge of screen

Изменение точки выравнивания всплывающего окна

Если Placement имеет значение AbsolutePoint, RelativePoint или MousePoint, точка выравнивания всплывающего окна изменяется, когда всплывающее окно достигает нижнего или правого края экрана.

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

Screenshot showing the Target area with the Popup alignment point going past the Screen Edge in the bottom-left corner.

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

New popup alignment point due to screen edge

Если Popup достигает нижнего и правого краев экрана, точка выравнивания всплывающего окна находится в правом нижнем углу Popup.

Изменение положения исходной точки и точки выравнивания всплывающего окна

Если Placement имеет значение Bottom, Left, Mouse, Right или Top, исходная точка и точка выравнивания всплывающего окна изменяются при достижении определенного края экрана. Край экрана, который вызывает изменение положения, зависит от значения PlacementMode.

На следующем рисунке показано, что если Placement имеет значение Bottom и Popup достигает нижнего края экрана, то исходной точкой является левый верхний угол целевой области, а точкой выравнивания всплывающего окна — левый нижний угол Popup.

Screenshot showing the Target area in the top half of the screen with the Popup alignment point on the bottom half of the screen with a Vertical Offset of 5.

На следующем рисунке показано, что если Placement имеет значение Left и Popup достигает левого края экрана, то исходной точкой является правый верхний угол целевой области, а точкой выравнивания всплывающего окна — левый верхний угол Popup.

New alignment point due to left screen edge

На следующем рисунке показано, что если Placement имеет значение Right и Popup достигает правого края экрана, то исходной точкой является левый верхний угол целевой области, а точкой выравнивания всплывающего окна — правый верхний угол Popup.

New alignment point due to right screen edge

На следующем рисунке показано, что если Placement имеет значение Top и Popup достигает верхнего края экрана, то исходной точкой является левый нижний угол целевой области, а точкой выравнивания всплывающего окна — левый верхний угол Popup.

New alignment point due to top screen edge

На следующем рисунке показано, что если Placement имеет значение Mouse и Popup достигает нижнего края экрана, то исходной точкой является левый верхний угол целевой области (границы указателя мыши), а точкой выравнивания всплывающего окна — левый нижний угол Popup.

new alignment point due to mouse near screen edge

Настройка размещения контекстного меню

Вы можете настроить исходную точку и точку выравнивания всплывающего окна, задав для свойства Placement значение Custom. Затем определите делегат CustomPopupPlacementCallback, который возвращает набор возможных точек размещения и основные оси (в порядке предпочтения) для Popup. Выбирается точка, в которой отображается наибольшая часть Popup. Расположение Popup автоматически корректируется, если граница экрана скрывает Popup. См. пример в разделе Указание пользовательского расположения контекстного меню.

См. также