Comment créer un contrôle de superposition au-dessus de tous les autres contrôles?

166

Je dois faire apparaître un contrôle au-dessus de tous les autres contrôles, afin qu'il les superpose partiellement.

user626528
la source

Réponses:

162

Si vous utilisez un Canvasou Griddans votre mise en page, donnez au contrôle à placer en haut un plus haut ZIndex.

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

Si vous ne spécifiez pas ZIndex, les enfants d'un panneau sont rendus dans l'ordre dans lequel ils sont spécifiés (c'est-à-dire le dernier en haut).

Si vous cherchez à faire quelque chose de plus compliqué, vous pouvez voir comment ChildWindowest implémenté dans Silverlight. Il superpose un arrière-plan semi-transparent et une fenêtre contextuelle sur l'ensemble de votre RootVisual.

foson
la source
Remarque: ce n'est pas comme le HTML Canvas comme je m'y attendais. Il n'est pas destiné au dessin direct, mais fournit un contexte de positionnement absolu (dans lequel vous mettriez généralement directement des formes).
Paul
73

Robert Rossney a une bonne solution. Voici une solution alternative que j'ai utilisée dans le passé qui sépare la «superposition» du reste du contenu. Cette solution tire parti de la propriété attachée Panel.ZIndexpour placer la "superposition" par-dessus tout le reste. Vous pouvez définir la visibilité de la «superposition» dans le code ou utiliser un fichier 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>
Schtroumpf du métro
la source
Cette superposition couvrira toute la fenêtre, pas seulement une zone spécifique.
Metro Schtroumpf
La meilleure solution qui soit! Je vous remercie!
Développeur
Exactement ce dont j'avais besoin pour poser un "écran de confidentialité" sur toute la fenêtre de mon application (par exemple pour masquer des informations sensibles si l'utilisateur s'éloigne de son bureau), avec très peu de code. Impressionnant!
Whitzz le
40

Les contrôles dans la même cellule d'une Grille sont rendus en arrière-plan. Donc, un moyen simple de placer un contrôle sur un autre est de le placer dans la même cellule.

Voici un exemple utile, qui fait apparaître un panneau qui désactive tout dans la vue (c'est-à-dire le contrôle utilisateur) avec un message occupé alors qu'une tâche de longue durée est exécutée (c'est-à-dire alors que la BusyMessagepropriété liée n'est pas nulle):

<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>
Robert Rossney
la source
23

Mettez le contrôle que vous souhaitez mettre au premier plan à la fin de votre code xaml. C'est à dire

<Grid>
  <TabControl ...>
  </TabControl>
  <Button Content="ALways on top of TabControl Button"/>
</Grid>
artos
la source
13

Il s'agit d'une fonction commune des ornements dans WPF. Les ornements apparaissent généralement au-dessus de tous les autres contrôles, mais les autres réponses qui mentionnent l'ordre z peuvent mieux convenir à votre cas.

CodeNaked
la source
3
<Canvas Panel.ZIndex="1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="570">
  <!-- YOUR XAML CODE -->
</Canvas>
Devam Mehta
la source