我想选择一个要单击的 UI 控件并将桌面屏幕的其余部分半透明地变灰。我在想位图绘制整个屏幕,但这是一个非常缓慢的过程。我想有人知道 WPF 中如何做到这一点。我没有WPF的经验。我想在 Windows 7 上执行此操作。
3 回答
基本上,您希望显示一个不可聚焦且不响应输入的顶级全屏透明窗口。然后,您可以使用此窗口手动绘制叠加层。我认为最简单的方法是在 Window 上覆盖 OnRender 并绘制一个填充整个窗口但使用剪贴蒙版(通过drawingContext.PushClip)的矩形来排除您想要不覆盖的区域。
编辑:
这是一个例子:
Window 应该是这样设置的:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
AllowsTransparency="True"
WindowStyle="None"
WindowState="Maximized"
Topmost="False"
Background="{x:Null}"
IsHitTestVisible="False">
</Window>
WindowStyle
和设置将WindowState
导致窗口最大化并与任务栏重叠。
Topmost
设置为 true 将导致窗口位于所有其他窗口的顶部,并IsHitTestVisible
导致鼠标单击“落空”。
警告:如果您设置此选项,您将遇到无法关闭的最顶层窗口,因为它不听键盘命令。您将需要在代码中的某处手动关闭窗口。可能您想创建一个全局鼠标挂钩来收听鼠标,并创建一个键盘挂钩来收听 ESC 或其他东西。
为了让人们远离他们自己,我在上面的示例中将 TopMost 设置为 False。只有在您知道如何/何时在某处的代码中关闭窗口时才将其更改为 true。
设置为 null ,Background
以便您可以在后面的代码中使用自定义绘图。
后面的代码与此类似:
public MainWindow()
{
InitializeComponent();
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
var screenGeometry = new RectangleGeometry(new Rect(0, 0, ActualWidth, ActualHeight));
var excludeRectangle = new RectangleGeometry(new Rect(200, 200, 150, 150));
drawingContext.PushClip(CombinedGeometry.Combine(screenGeometry,excludeRectangle, GeometryCombineMode.Exclude,null));
drawingContext.PushOpacity(.8);
drawingContext.DrawRectangle(Brushes.Black, null, new Rect(0, 0, ActualWidth, ActualHeight));
drawingContext.Pop();
drawingContext.Pop();
}
您将在其中为 excludeRectangle 使用正确的位置和大小。
如果您运行此代码,您将看到屏幕显示为灰色,除了左上角的一个小矩形。
我使用了这段代码。但看起来它没有使用 OnRender。它只显示白窗。
namespace GrayOutTEST
{
class MainWindow1 : Window
{
private Window window;
public MainWindow1() { }
public void CreateWindow()
{
window = new Window();
window.Title = "WIndow Title";
window.Height = Screen.PrimaryScreen.Bounds.Height;
window.Width = Screen.PrimaryScreen.Bounds.Width;
window.Topmost = false;
window.IsHitTestVisible = false;
window.AllowsTransparency = true;
window.WindowStyle = WindowStyle.None;
window.WindowState = WindowState.Maximized;
// window.Background = null;
window.Show();
}
public void CloseWindow()
{
window.Close();
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
var screenGeometry = new RectangleGeometry(new Rect(0, 0, ActualWidth, ActualHeight));
var excludeRectangle = new RectangleGeometry(new Rect(200, 200, 150, 150));
drawingContext.PushClip(CombinedGeometry.Combine(screenGeometry, excludeRectangle, GeometryCombineMode.Exclude, null));
drawingContext.PushOpacity(.8);
drawingContext.DrawRectangle(System.Windows.Media.Brushes.Black, null, new Rect(0, 0, ActualWidth, ActualHeight));
drawingContext.Pop(); drawingContext.Pop();
}
[STAThread]
static void Main(string[] args)
{
MainWindow1 w = new MainWindow1();
w.CreateWindow();
Console.Read();
}
}
}
如果你想模糊 MainWindow 并专注于新的 Popup 窗口,你可以检查这个:
System.Windows.Media.Effects.BlurEffect objBlur = new System.Windows.Media.Effects.BlurEffect();
((MainWindow)App.Current.MainWindow).Effect = objBlur;
mainFrame.Navigate(new PopUp_page1());
您也可以使用 Window 代替 Popup 窗口。
要删除效果:
((MainWindow)App.Current.MainWindow).Effect = null;