灰色的桌面屏幕除了c中选定的控件#

问题描述:

我想要选择一个UI控件被点击并半透明地灰显桌面屏幕的其余部分。我正在考虑整个屏幕的位图绘制,但这个过程非常缓慢。我想在WPF中有人知道如何做到这一点。我没有WPF的体验。我想在Windows 7上执行此操作。灰色的桌面屏幕除了c中选定的控件#

+0

像Vista/7的UAC的弹出? – 2011-04-28 22:01:00

+0

雅。像Windows 7的剪切工具一样 – Deku 2011-04-28 22:52:18

基本上,您希望显示不可聚焦且不响应输入的顶级全屏透明窗口。然后,您可以使用此窗口手动绘制叠加层。我认为最简单的方法是在窗口上重写OnRender并绘制一个填充整个窗口的矩形,但使用剪贴蒙版(通过drawingContext.PushClip)排除您想要保留的区域。

编辑:

下面是一个例子:

的窗口或许应该建立这样的:

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

WindowStyleWindowState设置将导致窗口最大化和重叠任务栏。 Topmost设置为true将导致该窗口位于所有其他窗口之上,并且IsHitTestVisible将导致鼠标点击“跌倒”。

警告:如果您设置此选项,您将被最高的窗口卡住,因为它不听取键盘命令,所以无法关闭。 您需要手动关闭代码中某处的窗口。可能你想要创建一个全局的鼠标钩来监听鼠标和一个键盘钩来监听ESC或其他东西。

为了节省自己的人,我在上面的例子中将TopMost设置为False。如果你已经知道如何/何时关闭代码中的窗口,只需将其更改为true。

Background设置为null,以便您可以在后面的代码中使用自定义绘图。

后面的代码与此类似:

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适当的位置和大小。

如果您运行此代码,您将看到屏幕变灰,除了左上角有一个小矩形。

+0

这很酷。谢谢。是否有可能在C#代码中添加Xaml,或者在Xaml中使用OnRender事件添加整个代码隐藏文件。我需要的原因是我想使用添加类型将其添加到PowerShell中 – Deku 2011-05-02 22:21:59

+0

我不知道关于PowerShell,但是您可以在没有XAML的情况下轻松地在C#中执行此操作。简单地创建一个从Window继承的类(System.Windows.Window - 你需要引用PresentationFramework.dll)并在那里重写OnRender。然后在C#中设置我在XAML中设置的属性,并通过Show()... – 2011-05-02 23:25:11

+0

手动显示窗口,并且由于您是新手,请务必在接受此问题的答案时回答您的问题。 - 欢迎使用stackoverflow。 – 2011-05-02 23:27:37

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

} 
} 
+0

您显示的是一个新窗口而不是MainWindow1。 您必须显示MainWindow1,因为这是您实施OnRender方法的地方。还将背景设置为空。 – 2011-05-04 00:25:49

+0

你可以采取整个CreateWindow的东西,并做你的w变量是类型MainWindow1并取消注释background = null;位,它应该工作。 – 2011-05-04 00:26:34

+0

谢谢!我纠正了它,并运行良好。 – Deku 2011-05-04 17:12:02

如果你想模糊主窗口,并专注于新弹出窗口,你可以检查此:

System.Windows.Media.Effects.BlurEffect objBlur = new System.Windows.Media.Effects.BlurEffect(); 
((MainWindow)App.Current.MainWindow).Effect = objBlur; 

mainFrame.Navigate(new PopUp_page1()); 

您还可以使用窗口,而不是弹出窗口中。

要删除的效果:

((MainWindow)App.Current.MainWindow).Effect = null;