Como fazer o controle de sobreposição acima de todos os outros controles?


166

Eu preciso fazer com que um controle apareça acima de todos os outros controles, para que eles se sobreponham parcialmente.

Respostas:


162

Se você estiver usando um Canvasou Gridem seu layout, dê um controle maior para que o controle seja colocado em cima ZIndex.

Do MSDN :

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="ZIndex Sample">
  <Canvas>
    <Rectangle Canvas.ZIndex="3" Width="100" Height="100" Canvas.Top="100" Canvas.Left="100" Fill="blue"/>
    <Rectangle Canvas.ZIndex="1" Width="100" Height="100" Canvas.Top="150" Canvas.Left="150" Fill="yellow"/>
    <Rectangle Canvas.ZIndex="2" Width="100" Height="100" Canvas.Top="200" Canvas.Left="200" Fill="green"/>

    <!-- Reverse the order to illustrate z-index property -->

    <Rectangle Canvas.ZIndex="1" Width="100" Height="100" Canvas.Top="300" Canvas.Left="200" Fill="green"/>
    <Rectangle Canvas.ZIndex="3" Width="100" Height="100" Canvas.Top="350" Canvas.Left="150" Fill="yellow"/>
    <Rectangle Canvas.ZIndex="2" Width="100" Height="100" Canvas.Top="400" Canvas.Left="100" Fill="blue"/>
  </Canvas>
</Page>

Se você não especificar ZIndex, os filhos de um painel serão renderizados na ordem em que são especificados (por exemplo, o último no topo).

Se você deseja fazer algo mais complicado, pode ver como isso ChildWindowé implementado no Silverlight. Sobrepõe um plano de fundo semitransparente e pop-up ao longo de todo o processo RootVisual.


Nota: Isso não é como o HTML Canvas como eu esperava. Não se destina ao desenho direto, mas fornece um contexto de posicionamento absoluto (no qual você normalmente colocaria formas diretamente).
Paul

73

Robert Rossney tem uma boa solução. Aqui está uma solução alternativa que eu usei no passado que separa a "Sobreposição" do restante do conteúdo. Esta solução tira proveito da propriedade anexada Panel.ZIndexpara colocar a "Sobreposição" em cima de tudo o resto. Você pode definir a visibilidade da "Sobreposição" no código ou usar a DataTrigger.

<Grid x:Name="LayoutRoot">

 <Grid x:Name="Overlay" Panel.ZIndex="1000" Visibility="Collapsed">
    <Grid.Background>
      <SolidColorBrush Color="Black" Opacity=".5"/>
    </Grid.Background>

    <!-- Add controls as needed -->
  </Grid>

  <!-- Use whatever layout you need -->
  <ContentControl x:Name="MainContent" />

</Grid>

Essa sobreposição cobrirá a janela inteira, não apenas uma área específica.
Metro Smurf

A melhor solução de sempre! Obrigado!
Desenvolvedor

Exatamente o que eu precisava para colocar uma "tela de privacidade" em toda a janela do meu aplicativo (por exemplo, para ocultar informações confidenciais se o usuário se afastar de sua mesa), com muito pouco código. Impressionante!
Whitzz 28/01

39

Os controles na mesma célula de uma grade são renderizados de frente para frente. Portanto, uma maneira simples de colocar um controle em cima de outro é colocá-lo na mesma célula.

Aqui está um exemplo útil, que exibe um painel que desativa tudo na exibição (ou seja, o controle do usuário) com uma mensagem ocupada enquanto uma tarefa de longa execução é executada (ou seja, enquanto a BusyMessagepropriedade vinculada não é nula):

<Grid>

    <local:MyUserControl DataContext="{Binding}"/>

    <Grid>
        <Grid.Style>
            <Style TargetType="Grid">
                <Setter Property="Visibility"
                        Value="Visible" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding BusyMessage}"
                                 Value="{x:Null}">
                        <Setter Property="Visibility"
                                Value="Collapsed" />
                    </DataTrigger>

                </Style.Triggers>
            </Style>
        </Grid.Style>
        <Border HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                Background="DarkGray"
                Opacity=".7" />
        <Border HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Background="White"
                Padding="20"
                BorderBrush="Orange"
                BorderThickness="4">
            <TextBlock Text="{Binding BusyMessage}" />
        </Border>
    </Grid>
</Grid>

23

Coloque o controle que você deseja trazer para a frente no final do seu código xaml. Ou seja,

<Grid>
  <TabControl ...>
  </TabControl>
  <Button Content="ALways on top of TabControl Button"/>
</Grid>

13

Essa é uma função comum dos Adorners no WPF. Os adorners geralmente aparecem acima de todos os outros controles, mas as outras respostas que mencionam a ordem z podem se encaixar melhor no seu caso.


3
<Canvas Panel.ZIndex="1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="570">
  <!-- YOUR XAML CODE -->
</Canvas>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.