2009-06-12 25 views
29

Estoy desarrollando una aplicación que recuerda las preferencias del usuario en cuanto a dónde se ubicó el formulario por última vez en la pantalla. En algunos casos, el usuario lo tendrá en una pantalla secundaria, y luego iniciará la aplicación más tarde sin la segunda pantalla (algunas veces haciendo que el formulario aparezca fuera de la pantalla). Otras veces, el usuario cambiará su resolución y obtendrá un efecto similar.Determinando si un formulario está completamente fuera de pantalla

Estaba esperando hacer esta comprobación en el controlador de evento Form_Shown. Básicamente, quiero determinar si el formulario está completamente fuera de la pantalla para que pueda volver a colocarlo.

Algún consejo?

+0

Debo mencionar que soy consciente de que puedo realizar alguna lógica complicado por conseguir la resolución de la pantalla, el tamaño y la ubicación de la forma, sin embargo, me esperaba algo un poco mas elegante. – Cody

+0

¿De verdad crees que es más elegante para colocar el formulario, verifica si está fuera de la resolución/tamaño y luego lo reposicionas? Una solución más elegante sería comprobar si va a colocarlo fuera de la pantalla ANTES de hacerlo. –

Respuesta

49

Comprobar con esta función si la forma es totalmente en la pantalla:

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

Comprobación solamente la parte superior izquierda punto si está en la pantalla:

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

Olvidé cómo hacer que el rectángulo de Formulario sea diferente, pero espero que esto ayude –

+0

Eso se ve muy bien, y no sabía que existía esa funcionalidad. Sin embargo, una pregunta: ¿no será falso si la ventana está parcialmente fuera de la pantalla? La pregunta pide completamente fuera de la pantalla. –

+0

sí, en realidad ... –

0

comprobar la resolución pantallas antes de la posición la ventana. Eso te permitirá averiguar si vas a ubicarlo fuera de los límites de la resolución, antes de que realmente lo hagas.

3

Viejo hilo, pero sigue siendo útil! Cody y Andrija- gracias por el código. Tuve que hacer un par de ajustes menores: en lugar de screen.WorkingArea.Intersect (formRectangle); Usé formRectangle.Intersect (screen.WorkingArea); ya que Intersecar() reemplaza su objeto con la intersección. Si el formulario está completamente fuera de la pantalla, formRectangle después de la intersección es (0,0,0,0) y Contains() devuelve verdadero. Así que también verifico si formRectangle Top, Left, Width y Height no son todos 0 antes de devolver verdadero. Ahora el código devuelve verdadero si alguna parte del formulario está en pantalla, y falso si ninguna parte está en pantalla.

+1

Gracias Sean! ¿Hay alguna manera de que podamos incorporar esta respuesta a la de Andrija para obtener una respuesta completa? – Cody

12

La combinación de todas las soluciones anteriores con el -method "IntersectsWith" y LINQ extensiones nos dan en pocas palabras:

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

¿No podría simplificarse aún más utilizando ['Form.ClientRectangle'] (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.clientrectangle.aspx) – Carsten

+1

Encajaría para la mayoría de los propósitos, aunque no incluiría la forma completa. Control.ClientRectangle en MSDN: "El área del cliente de un control son los límites del control, menos los elementos que no son del cliente, como barras de desplazamiento, bordes, barras de título y menús". (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.clientrectangle.aspx) –

+1

Puede usar ['Form.DesktopBounds'] (http://msdn.microsoft) .com/en-us/library/system.windows.forms.form.desktopbounds (v = vs.110) .aspx) – Dan

1

Para WPF (basado en la Matthias Loerkes respuesta)

agregar una referencia a System.Windows.Forms y 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

Solución completa aquí (basado en todas las respuestas). He agregado un parámetro MinPercentOnScreen donde al menos este% de píxeles debe estar visible en todas las pantallas/pantallas. Por lo tanto, si esto devuelve false, tendrá que volver a colocar la posición de la ventana en su valor predeterminado.

// 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; 
} 

Implementación:

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