添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Popup 控件在一个浮动在应用程序上的单独窗口中显示内容。 可通过使用 PlacementTarget Placement PlacementRectangle HorizontalOffset VerticalOffset 属性来指定 Popup 相对于控件、鼠标或屏幕的位置。 这些属性协同工作,使你可以灵活地指定 Popup 的位置。

ToolTip ContextMenu 类还定义了这五个属性,并且两者的行为相似。

定位 Popup

可将 Popup 相对于 UIElement 或整个屏幕进行放置。 以下示例创建了四个相对于 UIElement (在本例中,它是一个图像)的 Popup 控件。 所有这些 Popup 控件都将 PlacementTarget 属性设置为 image1 ,但每个 Popup 具有不同的 Placement 属性值。

<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 控件

这一简单的示例演示了如何设置 PlacementTargetPlacement 属性,但你可通过使用 PlacementRectangleHorizontalOffsetVerticalOffset 属性,更好地控制 Popup 的位置。

![注意]根据与手部相关的 Windows 设置,弹出窗口在顶部或底部显示时可能左对齐或右对齐。 上图演示了右手对齐方式,该对齐方式将弹出窗口放在左侧。

术语定义:Popup 解析

对于理解 PlacementTargetPlacementPlacementRectangleHorizontalOffsetVerticalOffset 属性彼此关联的方式以及它们与 Popup 关联的方式,以下术语非常实用:

  • “目标对象”

  • Popup 对齐点

    这些术语为引用 Popup 的各个方面及其关联的控件提供了一种便捷的方法。

    目标对象是与 Popup 关联的元素。 如果已设置 PlacementTarget 属性,则它指定目标对象。 如果未设置 PlacementTarget 并且 Popup 具有父级,则父级就是目标对象。 如果没有 PlacementTarget 值并且没有父级,则没有目标对象并且 Popup 相对于屏幕进行定位。

    以下示例创建了一个作为 Canvas 的子级的 Popup。 该示例未对 Popup 设置 PlacementTarget 属性。 Placement 的默认值为 PlacementMode.Bottom,因此 PopupCanvas 下方显示。

    <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 进行定位。

    以下示例创建了一个作为 Canvas 的子级的 Popup,但这一次将 PlacementTarget 设置为 ellipse1,因此 Popup 在 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 进行定位。

    对于 ToolTipPlacement 的默认值是 Mouse。 对于 ContextMenuPlacement 的默认值是 MousePoint。 这些值将在后面的“属性如何协同工作”部分中进行说明。

    目标区域是屏幕上与 Popup 相对的区域。 在前面的示例中,Popup 与目标对象的边界对齐,但在某些情况下,即使 Popup 具有目标对象,Popup 也将与其他边界对齐。 如果已设置 PlacementRectangle 属性,则目标区域与目标对象的边界不同。

    以下示例创建了两个 Canvas 对象,每个对象包含一个 Rectangle 和一个 Popup。 在这两种情况下,Popup 的目标对象都是 Canvas。 第一个 Canvas 中的 Popup 设置了 PlacementRectangle,其 XYWidthHeight 属性分别设置为 50、50、50 和 100。 第二个 Canvas 中的 Popup 未设置 PlacementRectangle。 因此,第一个 Popup 位于 PlacementRectangle 下方,而第二个 Popup 位于 Canvas 下方。 每个 Canvas 还包含一个 Rectangle,它与第一个 PopupPlacementRectangle 具有相同的边界。 请注意,PlacementRectangle 不会在应用程序中创建可见元素;该示例创建了一个表示 PlacementRectangleRectangle

    <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 对齐点分别是目标区域和 Popup 上用于定位定位的参照点。 可使用 HorizontalOffsetVerticalOffset 属性使 Popup 从目标区域偏移。 HorizontalOffsetVerticalOffset 相对于目标原点和 Popup 对齐点。 Placement 属性的值确定目标原点和 Popup 对齐点的位置。

    以下示例创建了一个 Popup,并将 HorizontalOffsetVerticalOffset 属性设置为 20。 Placement 属性设置为 Bottom(默认值),因此目标原点是目标区域的左下角,而 Popup 对齐点是 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>
    

    下图显示前面示例的结果。

    属性如何协同工作

    需要将 PlacementTargetPlacementRectanglePlacement 的值一起考虑,才可确定正确的目标区域、目标原点和 Popup 对齐点。 例如,如果 Placement 的值是 Mouse,则目标对象不存在、PlacementRectangle 将被忽略并且目标区域是鼠标指针的边界。 另一方面,如果 PlacementBottom,则 PlacementTarget 或父级决定目标对象,而 PlacementRectangle 决定目标区域。

    下表介绍了目标对象、目标区域、目标原点和 Popup 对齐点,并指示是否对每个 PlacementMode 枚举值使用 PlacementTargetPlacementRectangle

    PlacementMode “目标对象” Popup 对齐点 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 定义。 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 的左上角。 PlacementTarget 或父级。 目标对象或 PlacementRectangle(如果已设置)。 PlacementRectangle 相对于目标对象。 目标区域的左上角。 Popup 的左下角。

    下图显示了每个 PlacementMode 值的 Popup、目标区域、目标原点和 Popup 对齐点。 在每个图中,目标区域为黄色,而 Popup 为蓝色。

    底部放置位置为的弹出窗口。

    对屏幕边缘对齐

    Popup 可通过重新自行定位以与屏幕边缘对齐,使整个 Popup 在屏幕上可见。 出现这种情况时,目标原点和 Popup 对齐点之间的距离可能与 HorizontalOffsetVerticalOffset 的值不同。 当 PlacementAbsoluteCenterRelative 时,Popup 将自身与每个屏幕边缘对齐。 例如,假定 PopupPlacement 设置为 Relative 并将 VerticalOffset 设置为 100。 如果屏幕下边缘隐藏全部或部分 Popup,则 Popup 沿屏幕下边缘重新自行定位,并且目标原点和 Popup 对齐点之间的垂直距离小于 100。 下图演示了此情况。

    更改 Popup 对齐点

    如果 PlacementAbsolutePointRelativePointMousePoint,则当 Popup 到达屏幕下边缘或右边缘时,Popup 对齐点将发生更改。

    下图演示当屏幕下边缘隐藏全部或部分 Popup 时,Popup 对齐点为 Popup 的左下角。

    下图演示了当屏幕下边缘隐藏 Popup 时,Popup 对齐点为 Popup 的右上角。

    如果 Popup 到达屏幕的下边缘和右边缘,则 Popup 对齐点为 Popup 的右下角。

    更改目标原点和 Popup 对齐点

    PlacementBottomLeftMouseRightTop时,如果 Popup 到达某个屏幕边缘,则目标原点和 Popup 对齐点将发生更改。 导致位置变化的屏幕边缘取决于 PlacementMode 值。

    下图演示了当 PlacementBottom 并且 Popup 到达屏幕下边缘时,目标原点是目标区域的左上角,而 Popup 对齐点是 Popup 的左下角。

    下图演示了当 PlacementLeft 并且 Popup 到达屏幕左边缘时,目标原点是目标区域的右上角,而 Popup 对齐点是 Popup 的左上角。

    由于屏幕左边缘位置为 Left,因此新的对齐点

    下图演示了当 PlacementRight 并且 Popup 到达屏幕右边缘时,目标原点是目标区域的左上角,而 Popup 对齐点是 Popup 的右上角。

    由于右屏幕边缘位置为 Right,因此新的对齐点

    下图演示了当 PlacementTop 并且 Popup 到达屏幕上边缘时,目标原点是目标区域的左下角,而 Popup 对齐点是 Popup 的左上角。

    下图演示了当 PlacementMouse 并且 Popup 到达屏幕下边缘时,目标原点是目标区域(鼠标指针的边界)的左上角,而 Popup 对齐点是 Popup 的左下角。

    自定义 Popup 放置

    可通过将 Placement 属性设置为 Custom 来自定义目标原点和 Popup 对齐点。 然后定义一个 CustomPopupPlacementCallback 委托,该委托返回 Popup 的一组可能的放置点和主轴(按优先顺序排列)。 显示 Popup 最大部分的点被选中。 如果屏幕边缘隐藏了 Popup,则 Popup 的位置会自动调整。 有关示例,请参阅指定自定义 Popup 位置

  • Popup 放置示例
  •