我需要让一个控件出现在所有其他控件之上,这样它就会部分覆盖它们。
如果您在布局中使用
Canvas
或 Grid
,请将控件置于更高的 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
,面板的子项将按照指定的顺序呈现(即顶部的最后一个)。
如果你想做一些更复杂的事情,你可以看看
ChildWindow
是如何在Silverlight中实现的。它覆盖了半透明背景并弹出整个RootVisual
。
罗伯特·罗斯尼有一个很好的解决方案。这是我过去使用过的另一种解决方案,它将“覆盖”与其余内容分开。该解决方案利用附加属性
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>
网格同一单元格中的控件从后到前呈现。因此,将一个控件放在另一个控件之上的一种简单方法是将其放在同一个单元格中。
这是一个有用的示例,它会弹出一个面板,在执行长时间运行的任务时(即,当
BusyMessage
绑定属性不为空时),该面板会禁用视图(即用户控件)中的所有内容,并带有繁忙消息:
<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>
将要置于前面的控件放在 xaml 代码的末尾。即
<Grid>
<TabControl ...>
</TabControl>
<Button Content="ALways on top of TabControl Button"/>
</Grid>
这是WPF中Adorners的常用功能。装饰器通常出现在所有其他控件之上,但提到 z 顺序的其他答案可能更适合您的情况。
示例:
在控件的构造函数中:
Loaded += (sender, args) =>
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
GreenOverlayAdorner adorner = new GreenOverlayAdorner(this);
adornerLayer.Add(adorner);
};
GreenOverlayAdorner.cs
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
public class GreenOverlayAdorner : Adorner
{
public GreenOverlayAdorner(UIElement adornedElement)
: base(adornedElement)
{
}
protected override void OnRender(DrawingContext drawingContext)
{
Rect adornedElementRect = new Rect(this.AdornedElement.RenderSize);
// Draw semi-transparent green background
Brush brush = new SolidColorBrush(Color.FromArgb(128, 0, 255, 0)); // 50% transparent green
drawingContext.DrawRectangle(brush, null, adornedElementRect);
// Draw solid green line
Pen pen = new Pen(Brushes.Green, 2);
drawingContext.DrawLine(pen, adornedElementRect.TopLeft, adornedElementRect.BottomRight);
}
}
<Canvas Panel.ZIndex="1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="570">
<!-- YOUR XAML CODE -->
</Canvas>