Wie kann man die Overlay-Steuerung über alle anderen Steuerelemente stellen?

166

Ich muss ein Steuerelement über allen anderen Steuerelementen anzeigen lassen, damit es sie teilweise überlagert.

user626528
quelle

Antworten:

161

Wenn Sie ein Canvasoder Gridin Ihrem Layout verwenden, geben Sie dem Steuerelement, das oben platziert werden soll, einen höheren Wert ZIndex.

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

Wenn Sie nichts angeben ZIndex, werden die untergeordneten Elemente eines Bedienfelds in der angegebenen Reihenfolge gerendert (dh das letzte oben).

Wenn Sie etwas Komplizierteres tun möchten, können Sie sich ansehen, wie ChildWindowes in Silverlight implementiert ist. Es überlagert einen halbtransparenten Hintergrund und ein Popup über Ihrem gesamten Hintergrund RootVisual.

Foson
quelle
Hinweis: Dies entspricht nicht dem von mir erwarteten HTML-Canvas. Es ist nicht für das direkte Zeichnen gedacht, bietet jedoch einen absoluten Positionierungskontext (in den Sie normalerweise direkt Formen einfügen würden).
Paul
73

Robert Rossney hat eine gute Lösung. Hier ist eine alternative Lösung, die ich in der Vergangenheit verwendet habe und die das "Overlay" vom Rest des Inhalts trennt. Diese Lösung nutzt die angehängte Eigenschaft Panel.ZIndex, um die "Überlagerung" über alles andere zu platzieren. Sie können entweder die Sichtbarkeit der "Überlagerung" im Code festlegen oder a verwenden 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>
Metro Schlumpf
quelle
Diese Überlagerung deckt das gesamte Fenster ab, nicht nur einen bestimmten Bereich.
Metro Schlumpf
Die beste Lösung aller Zeiten! Danke dir!
Entwickler
Genau das, was ich brauchte, um einen "Datenschutzbildschirm" über mein gesamtes App-Fenster zu legen (z. B. um vertrauliche Informationen zu verbergen, wenn der Benutzer von seinem Schreibtisch weggeht), mit sehr wenig Code. Genial!
Whitzz
39

Steuerelemente in derselben Zelle eines Rasters werden von hinten nach vorne gerendert. Eine einfache Möglichkeit, ein Steuerelement über ein anderes zu legen, besteht darin, es in dieselbe Zelle zu legen.

Hier ist ein nützliches Beispiel, das ein Fenster öffnet, in dem alles in der Ansicht (dh das Benutzersteuerelement) mit einer Besetztmeldung deaktiviert wird, während eine lange laufende Aufgabe ausgeführt wird (dh während die BusyMessagegebundene Eigenschaft nicht null ist):

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

Setzen Sie das Steuerelement, das Sie einfügen möchten, am Ende Ihres xaml-Codes in den Vordergrund. Dh

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

Dies ist eine häufige Funktion von Adorners in WPF. Adorners erscheinen normalerweise über allen anderen Steuerelementen, aber die anderen Antworten, in denen die Z-Reihenfolge erwähnt wird, passen möglicherweise besser zu Ihrem Fall.

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