Pregunta

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 (a veces el formulario aparecerá fuera de la pantalla).Otras veces el usuario cambiará su resolución dando como resultado un efecto similar.

Esperaba hacer esta verificación en el controlador de eventos Form_Shown.Básicamente quiero determinar si el formulario está completamente fuera de la pantalla para poder reposicionarlo.

¿Algún consejo?

¿Fue útil?

Solución

Consulte con esta función si la forma es completamente 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 único punto superior izquierda 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;
}

Otros consejos

La combinación de todas las soluciones anteriores con el -method "IntersectsWith" y LINQ extensiones darnos en resumen:

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

Solución completa aquí (sobre la base de todas las respuestas). He añadido un MinPercentOnScreen parámetro donde al menos este% de píxeles debe ser visible en todas las pantallas / pantallas. Así que si esto vuelve false tendrá que mover la posición de la ventana por defecto.

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

Hilo antiguo, ¡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 Intersect() 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 Contiene() devuelve verdadero.Así que también verifico si formRectangle Top, Left, Ancho y Alto no son todos 0 antes de devolver verdadero.Ahora el código devuelve verdadero si alguna parte del formulario está en la pantalla y falso si no hay ninguna parte en la pantalla.

En WPF (basado en respuesta Matthias Loerkes)

Añadir 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));
}

Ninguno de estos trabajos si un monitor pasa a ser apagado. La función Screen.AllScreens siempre devolverá el número de pantallas, incluso si uno está apagado.

Compruebe la resolución de las pantallas antes de colocar la ventana. Eso permitirá a averiguar si donde va a colocarlo fuera de los límites de la resolución, antes de que realmente lo hace.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top