2

我想选择一个要单击的 UI 控件并将桌面屏幕的其余部分半透明地变灰。我在想位图绘制整个屏幕,但这是一个非常缓慢的过程。我想有人知道 WPF 中如何做到这一点。我没有WPF的经验。我想在 Windows 7 上执行此操作。

4

3 回答 3

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 使用正确的位置和大小。

如果您运行此代码,您将看到屏幕显示为灰色,除了左上角的一个小矩形。

于 2011-04-29T05:26:39.887 回答
0

我使用了这段代码。但看起来它没有使用 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();
    }

}
}
于 2011-05-03T22:27:07.357 回答
0

如果你想模糊 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;
于 2016-07-21T05:45:58.983 回答