灰色的桌面屏幕除了c中选定的控件#
我想要选择一个UI控件被点击并半透明地灰显桌面屏幕的其余部分。我正在考虑整个屏幕的位图绘制,但这个过程非常缓慢。我想在WPF中有人知道如何做到这一点。我没有WPF的体验。我想在Windows 7上执行此操作。灰色的桌面屏幕除了c中选定的控件#
基本上,您希望显示不可聚焦且不响应输入的顶级全屏透明窗口。然后,您可以使用此窗口手动绘制叠加层。我认为最简单的方法是在窗口上重写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>
的WindowStyle
和WindowState
设置将导致窗口最大化和重叠任务栏。 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适当的位置和大小。
如果您运行此代码,您将看到屏幕变灰,除了左上角有一个小矩形。
这很酷。谢谢。是否有可能在C#代码中添加Xaml,或者在Xaml中使用OnRender事件添加整个代码隐藏文件。我需要的原因是我想使用添加类型将其添加到PowerShell中 – Deku 2011-05-02 22:21:59
我不知道关于PowerShell,但是您可以在没有XAML的情况下轻松地在C#中执行此操作。简单地创建一个从Window继承的类(System.Windows.Window - 你需要引用PresentationFramework.dll)并在那里重写OnRender。然后在C#中设置我在XAML中设置的属性,并通过Show()... – 2011-05-02 23:25:11
手动显示窗口,并且由于您是新手,请务必在接受此问题的答案时回答您的问题。 - 欢迎使用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();
}
}
}
您显示的是一个新窗口而不是MainWindow1。 您必须显示MainWindow1,因为这是您实施OnRender方法的地方。还将背景设置为空。 – 2011-05-04 00:25:49
你可以采取整个CreateWindow的东西,并做你的w变量是类型MainWindow1并取消注释background = null;位,它应该工作。 – 2011-05-04 00:26:34
谢谢!我纠正了它,并运行良好。 – 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;
像Vista/7的UAC的弹出? – 2011-04-28 22:01:00
雅。像Windows 7的剪切工具一样 – Deku 2011-04-28 22:52:18