2011-04-28 64 views
2

我想要選擇一個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

回答

3

基本上,您希望顯示不可聚焦且不響應輸入的頂級全屏透明窗口。然後,您可以使用此窗口手動繪製疊加層。我認爲最簡單的方法是在窗口上重寫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

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(); 
    } 

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

0

如果你想模糊主窗口,並專注於新彈出窗口,你可以檢查此:

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;