2009-06-12 11 views
29

Sto sviluppando un'applicazione che ricorda le preferenze dell'utente in merito a dove il modulo si trovava l'ultima volta sullo schermo. In alcuni casi, l'utente lo avrà su uno schermo secondario e quindi farà partire l'app in un secondo momento senza la seconda schermata (a volte il modulo viene visualizzato fuori dallo schermo). Altre volte l'utente cambierà la propria risoluzione risultando in un effetto simile.Determinare se un modulo è completamente fuori dallo schermo

Speravo di fare questo controllo nel gestore di eventi Form_Shown. Fondamentalmente voglio determinare se il modulo è completamente fuori dallo schermo, quindi posso riposizionarlo.

Qualche consiglio?

+0

Devo dire che io sono consapevole che posso eseguire una logica difficile da ottenere la risoluzione dello schermo, le dimensioni e la posizione del modulo, però speravo in qualcosa di un po ' più elegante. – Cody

+0

Pensi davvero che sia più elegante posizionare il modulo, controllare se è esterno alla risoluzione/dimensione e poi riposizionarlo? Una soluzione più elegante sarebbe quella di verificare se stai andando a posizionarlo fuori dallo schermo PRIMA di farlo. –

risposta

49

Verificare con questa funzione se la forma è completamente sullo schermo:

public bool IsOnScreen(Form form) 
{ 
    Screen[] screens = Screen.AllScreens; 
    foreach(Screen screen in screens) 
    { 
     Rectangle formRectangle = new Rectangle(form.Left, form.Top, 
               form.Width, form.Height); 

     if(screen.WorkingArea.Contains(formRectangle)) 
     { 
     return true; 
     } 
    } 

    return false; 
} 

Controllo solo in alto a sinistra punto se è sullo schermo:

public bool IsOnScreen(Form form) 
{ 
    Screen[] screens = Screen.AllScreens; 
    foreach(Screen screen in screens) 
    { 
     Point formTopLeft = new Point(form.Left, form.Top); 

     if(screen.WorkingArea.Contains(formTopLeft)) 
     { 
     return true; 
     } 
    } 

    return false; 
} 
+0

Ho dimenticato come ottenere il rettangolo del modulo in un altro modo, ma spero che questo aiuti –

+0

che sembra davvero pulito, e non sapevo che esistesse la funzionalità. Una domanda però: non tornerà ancora falso se la finestra è solo parzialmente fuori dallo schermo? La domanda richiede completamente fuori schermo. –

+0

sì, in realtà ... –

0

controllare la risoluzione schermi prima posizione la finestra. Ciò ti consentirà di capire se hai intenzione di metterlo fuori dai limiti della risoluzione, prima di farlo effettivamente.

3

Vecchio thread, ma comunque utile! Cody e Andrija- grazie per il codice. Ho dovuto apportare un paio di piccoli aggiustamenti: Invece di screen.WorkingArea.Intersect (formRectangle); Ho usato formRectangle.Intersect (screen.WorkingArea); poiché Intersect() sostituisce il suo oggetto con l'intersezione. Se il modulo è completamente fuori dallo schermo, formRectangle dopo l'intersezione è (0,0,0,0) e Contains() restituisce true. Quindi controllo anche se formRectangle Top, Left, Width e Height non sono tutti 0 prima di restituire true. Ora il codice restituisce true se qualsiasi parte del modulo è sullo schermo e false se nessuna parte è sullo schermo.

+1

Grazie Sean! C'è un modo in cui possiamo incorporare questa risposta in Andrija per una risposta completa? – Cody

12

Combinando tutte le soluzioni di cui sopra con la -Metodo "IntersectsWith" e LINQ-extensions ci danno in breve:

public bool IsOnScreen(Form form) 
{ 
    // Create rectangle 
    Rectangle formRectangle = new Rectangle(form.Left, form.Top, form.Width, form.Height); 

    // Test 
    return Screen.AllScreens.Any(s => s.WorkingArea.IntersectsWith(formRectangle)); 
} 
+0

Non potrebbe essere ancora più semplificato usando ['Form.ClientRectangle'] (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.clientrectangle.aspx) – Carsten

+1

Si adatterebbe per la maggior parte degli scopi, sebbene non includa l'intera forma. Control.ClientRectangle in MSDN: "L'area client di un controllo è i limiti del controllo, meno gli elementi non client quali barre di scorrimento, bordi, barre del titolo e menu." (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.clientrectangle.aspx) –

+1

È possibile utilizzare ['Form.DesktopBounds'] (http://msdn.microsoft .com/it-it/library/system.windows.forms.form.desktopbounds (v = vs.110) aspx) – Dan

1

Per WPF (sulla base degli Matthias Loerkes risposta)

Aggiungere un riferimento a System.Windows.Forms e System.Drawing.

//using System.Windows.Forms; 

public bool IsOnScreen(Window window) 
{ 
    var windowRect = new System.Drawing.Rectangle((int)window.Left, (int)window.Top, (int)window.Width, (int)window.Height); 
    return Screen.AllScreens.Any(s => s.WorkingArea.IntersectsWith(windowRect)); 
} 
8

Soluzione completa qui (in base a tutte le risposte). Ho aggiunto un parametro MinPercentOnScreen in cui almeno questa percentuale di pixel deve essere visibile su tutti gli schermi/display. Pertanto, se restituisce false, sarà necessario riportare la posizione della finestra sui valori predefiniti.

// Return True if a certain percent of a rectangle is shown across the total screen area of all monitors, otherwise return False. 
public bool IsOnScreen(System.Drawing.Point RecLocation, System.Drawing.Size RecSize, double MinPercentOnScreen = 0.2) 
{ 
    double PixelsVisible = 0; 
    System.Drawing.Rectangle Rec = new System.Drawing.Rectangle(RecLocation, RecSize); 

    foreach (Screen Scrn in Screen.AllScreens) 
    { 
     System.Drawing.Rectangle r = System.Drawing.Rectangle.Intersect(Rec, Scrn.WorkingArea); 
     // intersect rectangle with screen 
     if (r.Width != 0 & r.Height != 0) 
     { 
      PixelsVisible += (r.Width * r.Height); 
      // tally visible pixels 
     } 
    } 
    return PixelsVisible >= (Rec.Width * Rec.Height) * MinPercentOnScreen; 
} 

Implementazione:

return IsOnScreen(this.Location, this.Size);