Ich möchte ein UI-Steuerelement auswählen, das angeklickt werden soll, und den Rest des Desktop-Bildschirms halbtransparent abdunkeln. Ich dachte daran, den gesamten Bildschirm mit Bitmap zu malen, aber das ist ein sehr langsamer Prozess. Ich vermute, dass jemand da draußen in WPF weiß, wie das geht. Ich habe keine Erfahrung mit WPF. Ich wollte das auf Windows 7 machen.
Antworten
Zu viele Anzeigen?Grundsätzlich möchten Sie ein oberflächiges Vollbild-Transparentfenster anzeigen, das nicht fokussierbar ist und nicht auf Eingaben reagiert. Sie können dann dieses Fenster verwenden, um das Overlay manuell zu zeichnen. Ich denke, der einfachste Weg wäre, OnRender im Fenster zu überschreiben und ein Rechteck zu zeichnen, das das gesamte Fenster ausfüllt, aber eine Clipping-Maske verwendet (über drawingContext.PushClip), um den Bereich auszuschließen, den Sie unbedeckt lassen möchten.
BEARBEITEN:
Hier ist ein Beispiel:
Das Fenster sollte wahrscheinlich wie folgt eingerichtet werden:
Die Einstellungen WindowStyle
und WindowState
bewirken, dass das Fenster maximiert ist und die Taskleiste überlappt. Topmost
auf true gesetzt bewirkt, dass das Fenster über allen anderen Fenstern liegt und IsHitTestVisible
bewirkt, dass die Mausklicks "durchfallen".
Warnung: Wenn Sie dies einstellen, werden Sie mit einem oben stehenden Fenster feststecken, das Sie nicht schließen können, da es nicht auf Tastenbefehle hört. Sie müssen das Fenster manuell irgendwo in Ihrem Code schließen. Wahrscheinlich möchten Sie einen globalen Maushaken erstellen, um Mausklicks zu hören, und einen Tastaturhaken, um auf ESC oder ähnliches zu hören.
Um die Leute vor sich selbst zu schützen, habe ich TopMost in obigem Beispiel auf False gesetzt. Ändern Sie es nur auf true, wenn Sie herausgefunden haben, wie/wann Sie das Fenster im Code schließen möchten.
Das Background
ist auf null gesetzt, damit Sie Ihre benutzerdefinierte Zeichnung im Code-Behind verwenden können.
Der Code im Code-Behind sieht ähnlich wie folgt aus:
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();
}
wo Sie die richtige Position und Größe für das excludeRectangle verwenden würden.
Wenn Sie diesen Code ausführen, sehen Sie den Bildschirm grau geschaltet, außer einem kleinen Rechteck oben links.
Ich habe diesen Code verwendet. Aber es sieht so aus, als ob er OnRender nicht verwendet. Es zeigt nur ein weißes Fenster.
namespace GrayOutTEST
{
class MainWindow1 : Window
{
private Window window;
public MainWindow1() { }
public void CreateWindow()
{
window = new Window();
window.Title = "Fenstertitel";
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();
}
}
}
Wenn Sie das MainWindow verwischen und sich auf das neue Popup-Fenster konzentrieren möchten, können Sie dies überprüfen:
System.Windows.Media.Effects.BlurEffect objBlur = new System.Windows.Media.Effects.BlurEffect();
((MainWindow)App.Current.MainWindow).Effect = objBlur;
mainFrame.Navigate(new PopUp_page1());
Sie können auch ein Fenster anstelle eines Popup-Fensters verwenden.
Um den Effekt zu entfernen:
((MainWindow)App.Current.MainWindow).Effect = null;