C'è un modo per determinare se una finestra WPF aperta è attualmente visibile in qualsiasi monitor connesso al desktop? Con visibile intendo che il rettangolo dei limiti della finestra si interseca con il rettangolo del desktop di uno qualsiasi dei monitor.Determina se una finestra WPF aperta è visibile su qualsiasi monitor
Ho bisogno di questa funzionalità per determinare se una finestra deve essere riposizionata perché la configurazione del monitor (limiti delle aree di lavoro, conteggio monitor) è cambiata tra riavvii della mia applicazione (che salva le posizioni della finestra).
sono venuto su con il codice qui sotto e sembra funzionare, ma ha diversi problemi:
- Ho bisogno di fare riferimento a forme finestre.
- Ho bisogno delle impostazioni DPI del desktop e trasformo i pixel reali dei moduli Windows in pixel virtuali WPF.
- Ho bisogno di un'istanza Visual acutal che è già stata sottoposta a rendering per eseguire la trasformazione.
Sei a conoscenza di una soluzione che risolve alcuni o tutti i 3 problemi sopra riportati?
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
internal static class Desktop
{
private static Size dpiFactor = new Size(1.0, 1.0);
private static bool isInitialized;
public static IEnumerable<Rect> WorkingAreas
{
get
{
return
Screen.AllScreens.Select(
screen =>
new Rect(
screen.WorkingArea.Left * dpiFactor.Width,
screen.WorkingArea.Top * dpiFactor.Height,
screen.WorkingArea.Width * dpiFactor.Width,
screen.WorkingArea.Height * dpiFactor.Height));
}
}
public static void TryInitialize(Visual visual)
{
if (isInitialized)
{
return;
}
var ps = PresentationSource.FromVisual(visual);
if (ps == null)
{
return;
}
var ct = ps.CompositionTarget;
if (ct == null)
{
return;
}
var m = ct.TransformToDevice;
dpiFactor = new Size(m.M11, m.M22);
isInitialized = true;
}
}
Uso del (inizializzato) Desktop
classe:
private bool IsLocationValid(Rect windowRectangle)
{
foreach (var workingArea in Desktop.WorkingAreas)
{
var intersection = Rect.Intersect(windowRectangle, workingArea);
var minVisible = new Size(10.0, 10.0);
if (intersection.Width >= minVisible.Width &&
intersection.Height >= minVisible.Height)
{
return true;
}
}
return false;
}
Aggiornamento
Uso dello schermo virtuale (SystemParameters.VirtualScreen*
) non funziona perché quando si utilizzano più monitor il "desktop "non è un semplice rettangolo. Potrebbe essere un poligono. Ci saranno punti ciechi nella schermata virtuale perché
- gli schermi collegati possono avere diverse risoluzioni
- è possibile configurare la posizione di ogni schermata.
http: // StackOverflow.it/questions/2465646/how-do-i-know-monitor-a-wpf-window-is-in – Flot2011
Sebbene la domanda da quel collegamento sia abbastanza simile, non risponde alla mia domanda. Ho già proposto una soluzione e mi piacerebbe trovare un modo per eliminare esplicitamente i tre problemi che ho menzionato. – bitbonk
Quindi le librerie WPF e C# non possono aiutarti. Potresti provare PInvoke, ma probabilmente è più sporco. Vedi questa domanda per ulteriori informazioni al riguardo: http://stackoverflow.com/questions/1927540/how-to-get-the-size-of-the-current-screen-in-wpf – AkselK