How to make overlay control above all other controls? How to make overlay control above all other controls? wpf wpf

How to make overlay control above all other controls?


If you are using a Canvas or Grid in your layout, give the control to be put on top a higher ZIndex.

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

If you don't specify ZIndex, the children of a panel are rendered in the order they are specified (i.e. last one on top).

If you are looking to do something more complicated, you can look at how ChildWindow is implemented in Silverlight. It overlays a semitransparent background and popup over your entire RootVisual.


Robert Rossney has a good solution. Here's an alternative solution I've used in the past that separates out the "Overlay" from the rest of the content. This solution takes advantage of the attached property Panel.ZIndex to place the "Overlay" on top of everything else. You can either set the Visibility of the "Overlay" in code or use 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>


Controls in the same cell of a Grid are rendered back-to-front. So a simple way to put one control on top of another is to put it in the same cell.

Here's a useful example, which pops up a panel that disables everything in the view (i.e. the user control) with a busy message while a long-running task is executed (i.e. while the BusyMessage bound property isn't null):

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