Comportamento de posicionamento do pop-up

Um controle de Popup exibe o conteúdo em uma janela separada acima de um aplicativo. Você pode especificar a posição de um Popup em relação a um controle, ao mouse ou à tela usando as propriedades PlacementTarget, Placement, PlacementRectangle, HorizontalOffset e VerticalOffset. Essas propriedades trabalham juntas para proporcionar flexibilidade no momento de especificar a posição do Popup.

Observação

As classes ToolTip e ContextMenu também definem essas cinco propriedades e se comportam de modo semelhante.

Posicionamento do pop-up

O posicionamento de um Popup pode ser relativo a um UIElement ou à tela inteira. O seguinte exemplo cria quatro controles de Popup que são relativos a um UIElement; nesse caso, é uma imagem. Todos os controles de Popup têm a propriedade PlacementTarget definida como image1, mas cada Popup tem um valor diferente para a propriedade de posicionamento.

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

A ilustração a seguir mostra a imagem e os controles de Popup

Image with four popup controls

Este exemplo simples demonstra como definir as propriedades PlacementTarget e Placement. Mas, usando as propriedades PlacementRectangle, HorizontalOffset e VerticalOffset, você tem ainda mais controle sobre onde o Popup está posicionado.

! [NOTA] Dependendo das configurações do Windows relacionadas à lateralidade, o pop-up pode estar alinhado à esquerda ou à direita quando mostrado na parte superior ou inferior. A imagem anterior demonstra o alinhamento destro, que coloca o pop-up à esquerda.

Definições de termos: a anatomia de um pop-up

Os termos a seguir são úteis para entender como as propriedades PlacementTarget, Placement, PlacementRectangle, HorizontalOffset e VerticalOffset se relacionam entre si e ao Popup:

  • Objeto de destino

  • Área de destino

  • Origem do destino

  • Ponto de alinhamento do pop-up

Esses termos oferecem um modo conveniente de se referir a vários aspectos do Popup e ao controle associado a ele.

Objeto de Destino

O objeto de destino é o elemento ao qual o Popup está associado. Se a propriedade PlacementTarget for definida, ela especificará o objeto de destino. Se PlacementTarget não for definido e Popup tiver um pai, o pai será o objeto de destino. Se não houver nenhum valor PlacementTarget e nenhum pai, não haverá nenhum objeto de destino e o Popup será posicionado em relação à tela.

O seguinte exemplo cria um Popup que é o filho de um Canvas. O exemplo não define a propriedade PlacementTarget no Popup. O valor padrão para Placement é PlacementMode.Bottom. Portanto, o Popup aparece abaixo do 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>

A seguinte ilustração mostra que o Popup está posicionado em relação ao Canvas.

Popup control with no PlacementTarget

O seguinte exemplo cria um Popup que é o filho de um Canvas, mas dessa vez o PlacementTarget é definido como ellipse1. Portanto, o pop-up aparece abaixo do 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>

A seguinte ilustração mostra que o Popup está posicionado em relação ao Ellipse.

Popup positioned relative to an ellipse

Observação

Para ToolTip, o valor padrão de Placement é Mouse. Para ContextMenu, o valor padrão de Placement é MousePoint. Esses valores são explicados posteriormente, em “Como as propriedades funcionam juntas”.

Área de destino

A área de destino é a área na tela à qual o Popup é relativo. Nos exemplos anteriores, o Popup está alinhado com os limites do objeto de destino, mas, em alguns casos, o Popup está alinhado a outros limites, mesmo que o Popup tenha um objeto de destino. Se a propriedade PlacementRectangle for definida, a área de destino será diferente dos limites do objeto de destino.

O seguinte exemplo cria dois objetos Canvas, cada um contendo um Rectangle e um Popup. Em ambos os casos, o objeto de destino para o Popup é o Canvas. O PlacementRectangle do Popup no primeiro Canvas está definido, com as propriedades X, Y, Width e Height definidas como 50, 50, 50 e 100, respectivamente. O PlacementRectangle do Popup no segundo Canvas não está definido. Como resultado, o primeiro Popup está posicionado abaixo de PlacementRectangle e o segundo Popup está posicionado abaixo de Canvas. Cada Canvas também contém um Rectangle que tem os mesmos limites que o PlacementRectangle do primeiro Popup. Observe que o PlacementRectangle não cria um elemento visível no aplicativo. O exemplo cria um Rectangle para representar o 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>

A ilustração a seguir mostra o resultado do exemplo anterior.

Popup with and without PlacementRectangle

Origem do destino e ponto de alinhamento do pop-up

A origem do destino e o ponto de alinhamento do pop-up são pontos de referência na área de destino e no pop-up, respectivamente, usados para posicionamento. Você pode usar as propriedades HorizontalOffset e VerticalOffset para deslocar o pop-up da área de destino. O HorizontalOffset e o VerticalOffset são relativos à origem de destino e ao ponto de alinhamento do pop-up. O valor da propriedade Placement determina onde a origem de destino e o ponto de alinhamento do pop-up estão localizados.

O seguinte exemplo cria um Popup e define as propriedades HorizontalOffset e VerticalOffset para 20. A propriedade Placement é definida como Bottom (padrão). Portanto, a origem de destino está no canto inferior esquerdo da área de destino e o ponto de alinhamento do pop-up está no canto superior esquerdo do 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>

A ilustração a seguir mostra o resultado do exemplo anterior.

Popup placement with target origin alignment point

Como as propriedades trabalham juntas

Os valores de PlacementTarget, PlacementRectangle e Placement precisam ser considerados em conjunto para descobrir a área de destino, a origem de destino e o ponto de alinhamento do pop-up corretos. Por exemplo, se o valor de Placement for Mouse, não haverá nenhum objeto de destino, o PlacementRectangle será ignorado e a área de destino será o limite do ponteiro do mouse. Por outro lado, se Placement for Bottom, o PlacementTarget ou o pai determinará o objeto de destino e PlacementRectangle determinará a área de destino.

A seguinte tabela descreve o objeto de destino, a área de destino, a origem de destino e o ponto de alinhamento do pop-up e indica se PlacementTarget e PlacementRectangle são usados para cada valor de enumeração de PlacementMode.

PlacementMode Objeto de destino Área de destino Origem do destino Ponto de alinhamento do pop-up
Absolute Não aplicável. PlacementTarget é ignorado. A tela ou PlacementRectangle, se ele estiver configurado. O PlacementRectangle é relativo à tela. O canto superior esquerdo da área de destino. O canto superior esquerdo do Popup.
AbsolutePoint Não aplicável. PlacementTarget é ignorado. A tela ou PlacementRectangle, se ele estiver configurado. O PlacementRectangle é relativo à tela. O canto superior esquerdo da área de destino. O canto superior esquerdo do Popup.
Bottom O PlacementTarget ou o pai. O objeto de destino ou o PlacementRectangle, se ele estiver definido. O PlacementRectangle é relativo ao objeto de destino. O canto inferior esquerdo da área de destino. O canto superior esquerdo do Popup.
Center O PlacementTarget ou o pai. O objeto de destino ou o PlacementRectangle, se ele estiver definido. O PlacementRectangle é relativo ao objeto de destino. O centro da área de destino. O centro do Popup.
Custom O PlacementTarget ou o pai. O objeto de destino ou o PlacementRectangle, se ele estiver definido. O PlacementRectangle é relativo ao objeto de destino. Definido por CustomPopupPlacementCallback. Definido por CustomPopupPlacementCallback.
Left O PlacementTarget ou o pai. O objeto de destino ou o PlacementRectangle, se ele estiver definido. O PlacementRectangle é relativo ao objeto de destino. O canto superior esquerdo da área de destino. A parte superior direita do Popup.
Mouse Não aplicável. PlacementTarget é ignorado. Os limites do ponteiro do mouse. PlacementRectangle é ignorado. O canto inferior esquerdo da área de destino. O canto superior esquerdo do Popup.
MousePoint Não aplicável. PlacementTarget é ignorado. Os limites do ponteiro do mouse. PlacementRectangle é ignorado. O canto superior esquerdo da área de destino. O canto superior esquerdo do Popup.
Relative O PlacementTarget ou o pai. O objeto de destino ou o PlacementRectangle, se ele estiver definido. O PlacementRectangle é relativo ao objeto de destino. O canto superior esquerdo da área de destino. O canto superior esquerdo do Popup.
RelativePoint O PlacementTarget ou o pai. O objeto de destino ou o PlacementRectangle, se ele estiver definido. O PlacementRectangle é relativo ao objeto de destino. O canto superior esquerdo da área de destino. O canto superior esquerdo do Popup.
Right O PlacementTarget ou o pai. O objeto de destino ou o PlacementRectangle, se ele estiver definido. O PlacementRectangle é relativo ao objeto de destino. O canto superior direito da área de destino. O canto superior esquerdo do Popup.
Top O PlacementTarget ou o pai. O objeto de destino ou o PlacementRectangle, se ele estiver definido. O PlacementRectangle é relativo ao objeto de destino. O canto superior esquerdo da área de destino. O canto inferior esquerdo do Popup.

As seguintes ilustrações mostram Popup, a área de destino, a origem do destino e o ponto de alinhamento do pop-up para cada valor de PlacementMode. Em cada figura, a área de destino é amarela e o Popup é azul.

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

Quando o pop-up encontra a borda da tela

Por motivos de segurança, um Popup não pode ser ocultado pela borda de uma tela. Uma das três ações a seguir ocorre quando o Popup encontra uma borda da tela:

  • O pop-up é realinhado na borda da tela que obscureceria o Popup.

  • O pop-up usa um ponto de alinhamento do pop-up diferente.

  • O pop-up usa uma origem do destino e um ponto de alinhamento do pop-up diferentes.

Essas opções são descritas detalhadamente mais adiante nesta seção.

O comportamento do Popup ao encontrar uma borda da tela depende do valor da propriedade Placement e de qual borda da tela o pop-up encontra. A seguinte tabela resume o comportamento quando o Popup encontra uma borda da tela para cada valor de PlacementMode.

PlacementMode Borda superior Borda inferior Borda esquerda Borda direita
Absolute Alinha-se com a borda superior. Alinha-se com a borda inferior. Alinha-se com a borda esquerda. Alinha-se com a borda direita.
AbsolutePoint Alinha-se com a borda superior. O ponto de alinhamento do pop-up é alterado para o canto inferior esquerdo do Popup. Alinha-se com a borda esquerda. O ponto de alinhamento do pop-up é alterado para o canto superior direito do Popup.
Bottom Alinha-se com a borda superior. A origem do destino é alterada para o canto superior esquerdo da área de destino e o ponto de alinhamento do pop-up é alterado para o canto inferior esquerdo do Popup. Alinha-se com a borda esquerda. Alinha-se com a borda direita.
Center Alinha-se com a borda superior. Alinha-se com a borda inferior. Alinha-se com a borda esquerda. Alinha-se com a borda direita.
Left Alinha-se com a borda superior. Alinha-se com a borda inferior. A origem do destino é alterada para o canto superior direito da área de destino e o ponto de alinhamento do pop-up é alterado para o canto inferior esquerdo do Popup. Alinha-se com a borda direita.
Mouse Alinha-se com a borda superior. A origem do destino é alterada para o canto superior esquerdo da área de destino (os limites do ponteiro do mouse) e o ponto de alinhamento do pop-up é alterado para o canto inferior esquerdo do Popup. Alinha-se com a borda esquerda. Alinha-se com a borda direita.
MousePoint Alinha-se com a borda superior. O ponto de alinhamento do pop-up é alterado para o canto inferior esquerdo do Popup. Alinha-se com a borda esquerda. O ponto de alinhamento do pop-up muda para o canto superior direito do pop-up.
Relative Alinha-se com a borda superior. Alinha-se com a borda inferior. Alinha-se com a borda esquerda. Alinha-se com a borda direita.
RelativePoint Alinha-se com a borda superior. O ponto de alinhamento do pop-up é alterado para o canto inferior esquerdo do Popup. Alinha-se com a borda esquerda. O ponto de alinhamento do pop-up muda para o canto superior direito do pop-up.
Right Alinha-se com a borda superior. Alinha-se com a borda inferior. Alinha-se com a borda esquerda. A origem do destino é alterada para o canto superior esquerdo da área de destino e o ponto de alinhamento do pop-up é alterado para o canto superior direito do Popup.
Top A origem do destino é alterada para o canto inferior esquerdo da área de destino e o ponto de alinhamento do pop-up é alterado para o canto superior esquerdo do Popup. Com efeito, o mesmo ocorre quando Placement é Bottom. Alinha-se com a borda inferior. Alinha-se com a borda esquerda. Alinha-se com a borda direita.

Alinhamento com a borda da tela

Um Popup pode alinhar-se à borda da tela reposicionando-se, de modo que todo o Popup fique visível na tela. Quando isso ocorre, a distância entre a origem do destino e o ponto de alinhamento do pop-up pode diferir dos valores de HorizontalOffset e VerticalOffset. Quando Placement for Absolute, Center ou Relative, o Popup se alinhará a cada borda da tela. Por exemplo, suponha que Placement do Popup seja definido como Relative e o VerticalOffset seja definido como 100. Se a borda inferior da tela ocultar a totalidade ou parte do Popup, o Popup se reposicionará ao longo da borda inferior da tela e a distância vertical entre a origem do destino e o ponto de alinhamento do pop-up será inferior a 100. A ilustração a seguir demonstra isso.

Popup that aligns to edge of screen

Alterando o ponto de alinhamento do pop-up

Se Placement for AbsolutePoint, RelativePoint ou MousePoint, o ponto de alinhamento do pop-up será alterado quando o pop-up encontrar a borda inferior ou direita da tela.

A seguinte ilustração demonstra que, quando a borda inferior da tela oculta a totalidade ou parte do Popup, o ponto de alinhamento do pop-up será o canto inferior esquerdo do Popup.

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

A seguinte ilustração demonstra que, quando o Popup estiver oculto pela borda direita da tela, o ponto de alinhamento do pop-up será no canto superior direito do Popup.

New popup alignment point due to screen edge

Se o Popup encontrar as bordas inferior e direita da tela, o ponto de alinhamento do pop-up será no canto inferior direito do Popup.

Mudando a origem do destino e o ponto de alinhamento do pop-up

Quando Placement for Bottom, Left, Mouse, Right ou Top, a origem de destino e o ponto de alinhamento do pop-up serão alterados se uma determinada borda da tela for encontrada. A borda da tela que faz com que a posição seja alterada depende do valor de PlacementMode.

A seguinte ilustração demonstra que, quando Placement for Bottom e o Popup encontrar a borda inferior da tela, a origem de destino será no canto superior esquerdo da área de destino e o ponto de alinhamento do pop-up será no canto inferior esquerdo do 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.

A seguinte ilustração demonstra que, quando Placement for Left e o Popup encontrar a borda esquerda da tela, a origem de destino será no canto superior direito da área de destino e o ponto de alinhamento do pop-up será no canto superior esquerdo do Popup.

New alignment point due to left screen edge

A seguinte ilustração demonstra que, quando Placement for Right e o Popup encontrar a borda direita da tela, a origem de destino será no canto superior esquerdo da área de destino e o ponto de alinhamento do pop-up será no canto superior direito do Popup.

New alignment point due to right screen edge

A seguinte ilustração demonstra que, quando Placement for Top e o Popup encontrar a borda superior da tela, a origem de destino será no canto inferior esquerdo da área de destino e o ponto de alinhamento do pop-up será no canto superior esquerdo do Popup.

New alignment point due to top screen edge

A seguinte ilustração demonstra que, quando Placement for Mouse e o Popup encontrar a borda inferior da tela, a origem de destino será no canto superior esquerdo da área de destino (os limites do ponteiro do mouse) e o ponto de alinhamento do pop-up será no canto inferior esquerdo do Popup.

new alignment point due to mouse near screen edge

Personalizando o posicionamento do pop-up

Você pode personalizar a origem de destino e o ponto de alinhamento do pop-up configurando a propriedade Placement como Custom. Em seguida, defina um delegado CustomPopupPlacementCallback que retorna um conjunto de possíveis pontos de posicionamento e eixos primários (em ordem de preferência) para o Popup. O ponto que mostra a maior parte do Popup está selecionado. A posição de Popup será ajustada automaticamente se o Popup estiver oculto pela borda da tela. Para ver um exemplo, consulte Especificar uma posição de pop-up personalizada.

Confira também