如何使叠加控件位于所有其他控件之上?

197

我需要让一个控件出现在其他所有控件的上面,以便它可以部分地覆盖它们。

6个回答

192
如果您在布局中使用了CanvasGrid,请将要放置在顶部的控件赋予更高的ZIndex
引自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>
如果未指定 ZIndex,则面板的子元素将按照它们的顺序进行渲染(即最后一个在顶部)。
如果您想执行更复杂的操作,可以查看 Silverlight 中 ChildWindow 的实现方式。它会在整个 RootVisual 上叠加半透明背景和弹出窗口。

注意:这不像我预期的HTML画布。它不是用于直接绘图,而是提供了一个绝对定位的上下文(通常您会直接将形状放入其中)。 - Paul
为什么无论我使用Canvas还是Grid,WebBrowser标签总是在所有子元素的上方? - makri aymen abderraouf

93

Robert Rossney提供了一个很好的解决方案。我曾经使用过一种另外的解决方案,将"覆盖层(Overlay)"与其余内容分开处理。这种解决方案利用了附加属性Panel.ZIndex来将"覆盖层"放置在所有其他内容上面。您可以通过代码设置"覆盖层"的可见性或使用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>

1
这个覆盖层将覆盖整个窗口,而不仅仅是特定的区域。 - Metro Smurf
1
有史以来最好的解决方案!谢谢! - NoWar
1
正是我需要的,可以在整个应用程序窗口上放置“隐私屏幕”(例如,如果用户离开他的桌子,隐藏敏感信息),而且只需很少的代码。太棒了! - Whitzz

44

在网格的同一单元格中,控件是按照反向渲染的。 因此,将一个控件放在另一个控件的顶部的简单方法是将其放置在同一单元格中。

下面是一个有用的示例,它弹出一个面板,在执行长时间任务时(即当绑定属性 BusyMessage 不为 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>

25
将你想要置于最前方的控件放在 XAML 代码的末尾。例如:
<Grid>
  <TabControl ...>
  </TabControl>
  <Button Content="ALways on top of TabControl Button"/>
</Grid>

17

这是WPF中装饰器的常见功能。装饰器通常出现在所有其他控件的上方,但提到Z顺序的其他答案可能更适合您的情况。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接