Sé que puedo obtener el tamaño de la pantalla principal usando
System.Windows.SystemParameters.PrimaryScreenWidth;
System.Windows.SystemParameters.PrimaryScreenHeight;
Pero, ¿cómo obtengo el tamaño de la pantalla actual? (Los usuarios de pantallas múltiples no siempre usan la pantalla principal y no todas las pantallas usan la misma resolución, ¿verdad?)
Sería bueno poder acceder al tamaño desde XAML, pero hacerlo desde el código (C #) sería suficiente.
Respuestas:
Hasta donde yo sé, no existe una función WPF nativa para obtener las dimensiones del monitor actual. En su lugar, podría PInvoke funciones nativas de varios monitores de pantalla , envolverlas en una clase administrada y exponer todas las propiedades que necesita para consumirlas desde XAML.
fuente
Creé un pequeño envoltorio alrededor de la pantalla de System.Windows.Forms, actualmente todo funciona ... Aunque no estoy seguro acerca de los "píxeles independientes del dispositivo".
public class WpfScreen { public static IEnumerable<WpfScreen> AllScreens() { foreach (Screen screen in System.Windows.Forms.Screen.AllScreens) { yield return new WpfScreen(screen); } } public static WpfScreen GetScreenFrom(Window window) { WindowInteropHelper windowInteropHelper = new WindowInteropHelper(window); Screen screen = System.Windows.Forms.Screen.FromHandle(windowInteropHelper.Handle); WpfScreen wpfScreen = new WpfScreen(screen); return wpfScreen; } public static WpfScreen GetScreenFrom(Point point) { int x = (int) Math.Round(point.X); int y = (int) Math.Round(point.Y); // are x,y device-independent-pixels ?? System.Drawing.Point drawingPoint = new System.Drawing.Point(x, y); Screen screen = System.Windows.Forms.Screen.FromPoint(drawingPoint); WpfScreen wpfScreen = new WpfScreen(screen); return wpfScreen; } public static WpfScreen Primary { get { return new WpfScreen(System.Windows.Forms.Screen.PrimaryScreen); } } private readonly Screen screen; internal WpfScreen(System.Windows.Forms.Screen screen) { this.screen = screen; } public Rect DeviceBounds { get { return this.GetRect(this.screen.Bounds); } } public Rect WorkingArea { get { return this.GetRect(this.screen.WorkingArea); } } private Rect GetRect(Rectangle value) { // should x, y, width, height be device-independent-pixels ?? return new Rect { X = value.X, Y = value.Y, Width = value.Width, Height = value.Height }; } public bool IsPrimary { get { return this.screen.Primary; } } public string DeviceName { get { return this.screen.DeviceName; } } }
fuente
Aquí amigo. Esto le dará solo el ancho y alto del área de trabajo.
System.Windows.SystemParameters.WorkArea.Width System.Windows.SystemParameters.WorkArea.Height
fuente
Esto le dará la pantalla actual basada en la parte superior izquierda de la ventana, simplemente llame a this.CurrentScreen () para obtener información sobre la pantalla actual.
using System.Windows; using System.Windows.Forms; namespace Common.Helpers { public static class WindowHelpers { public static Screen CurrentScreen(this Window window) { return Screen.FromPoint(new System.Drawing.Point((int)window.Left,(int)window.Top)); } } }
fuente
Tómese el tiempo para explorar los miembros de SystemParameters.
VirtualScreenWidth
VirtualScreenHeight
Estos incluso tienen en cuenta las posiciones relativas de las pantallas.
Solo probado con dos monitores.
fuente
¿Por qué no usar esto?
var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow); var activeScreen = Screen.FromHandle(interopHelper.Handle);
fuente
System.Windows.Forms.Screen
para hacer frente al píxel independiente del dispositivoSi está familiarizado con el uso de la clase System.Windows.Forms , puede agregar una referencia de la clase System.Windows.Forms a su proyecto:
Explorador de soluciones -> Referencias -> Agregar referencias ... -> (Ensamblados: Marco) -> desplácese hacia abajo y verifique el ensamblaje System.Windows.Forms -> Aceptar .
Ahora puede agregar usando System.Windows.Forms; declaración y use la pantalla en su proyecto wpf como antes.
fuente
También necesitaba la dimensión actual de la pantalla, específicamente el área de trabajo, que devolvió el rectángulo excluyendo el ancho de la barra de tareas.
Lo usé para reposicionar una ventana, que se abre hacia la derecha y hacia abajo hasta donde está posicionado el mouse. Dado que la ventana es bastante grande, en muchos casos salió de los límites de la pantalla. El siguiente código se basa en @ej respuesta: Esto le dará la pantalla actual ... . La diferencia es que también muestro mi algoritmo de reposicionamiento, que supongo que es en realidad el punto.
El código:
using System.Windows; using System.Windows.Forms; namespace MySample { public class WindowPostion { /// <summary> /// This method adjust the window position to avoid from it going /// out of screen bounds. /// </summary> /// <param name="topLeft">The requiered possition without its offset</param> /// <param name="maxSize">The max possible size of the window</param> /// <param name="offset">The offset of the topLeft postion</param> /// <param name="margin">The margin from the screen</param> /// <returns>The adjusted position of the window</returns> System.Drawing.Point Adjust(System.Drawing.Point topLeft, System.Drawing.Point maxSize, int offset, int margin) { Screen currentScreen = Screen.FromPoint(topLeft); System.Drawing.Rectangle rect = currentScreen.WorkingArea; // Set an offset from mouse position. topLeft.Offset(offset, offset); // Check if the window needs to go above the task bar, // when the task bar shadows the HUD window. int totalHight = topLeft.Y + maxSize.Y + margin; if (totalHight > rect.Bottom) { topLeft.Y -= (totalHight - rect.Bottom); // If the screen dimensions exceed the hight of the window // set it just bellow the top bound. if (topLeft.Y < rect.Top) { topLeft.Y = rect.Top + margin; } } int totalWidth = topLeft.X + maxSize.X + margin; // Check if the window needs to move to the left of the mouse, // when the HUD exceeds the right window bounds. if (totalWidth > rect.Right) { // Since we already set an offset remove it and add the offset // to the other side of the mouse (2x) in addition include the // margin. topLeft.X -= (maxSize.X + (2 * offset + margin)); // If the screen dimensions exceed the width of the window // don't exceed the left bound. if (topLeft.X < rect.Left) { topLeft.X = rect.Left + margin; } } return topLeft; } } }
Algunas explicaciones:
1) topLeft - position of the top left at the desktop (works for multi screens - with different aspect ratio). Screen1 Screen2 ─ ┌───────────────────┐┌───────────────────┐ Screen3 ▲ │ ││ │┌─────────────────┐ ─ │ │ ││ ││ ▼- │ ▲ 1080 │ │ ││ ││ │ │ │ │ ││ ││ │ │ 900 ▼ │ ││ ││ │ ▼ ─ └──────┬─────┬──────┘└──────┬─────┬──────┘└──────┬────┬─────┘ ─ ─┴─────┴─ ─┴─────┴─ ─┴────┴─ │◄─────────────────►││◄─────────────────►││◄───────────────►│ 1920 1920 1440 If the mouse is in Screen3 a possible value might be: topLeft.X=4140 topLeft.Y=195 2) offset - the offset from the top left, one value for both X and Y directions. 3) maxSize - the maximal size of the window - including its size when it is expanded - from the following example we need maxSize.X = 200, maxSize.Y = 150 - To avoid the expansion being out of bound. Non expanded window: ┌──────────────────────────────┐ ─ │ Window Name [X]│ ▲ ├──────────────────────────────┤ │ │ ┌─────────────────┐ │ │ 100 │ Text1: │ │ │ │ │ └─────────────────┘ │ │ │ [▼] │ ▼ └──────────────────────────────┘ ─ │◄────────────────────────────►│ 200 Expanded window: ┌──────────────────────────────┐ ─ │ Window Name [X]│ ▲ ├──────────────────────────────┤ │ │ ┌─────────────────┐ │ │ │ Text1: │ │ │ │ │ └─────────────────┘ │ │ 150 │ [▲] │ │ │ ┌─────────────────┐ │ │ │ Text2: │ │ │ │ │ └─────────────────┘ │ ▼ └──────────────────────────────┘ ─ │◄────────────────────────────►│ 200 4) margin - The distance the window should be from the screen work-area - Example: ┌─────────────────────────────────────────────────────────────┐ ─ │ │ ↕ Margin │ │ ─ │ │ │ │ │ │ │ ┌──────────────────────────────┐ │ │ │ Window Name [X]│ │ │ ├──────────────────────────────┤ │ │ │ ┌─────────────────┐ │ │ │ │ Text1: │ │ │ │ │ │ └─────────────────┘ │ │ │ │ [▲] │ │ │ │ ┌─────────────────┐ │ │ │ │ Text2: │ │ │ │ │ │ └─────────────────┘ │ │ │ └──────────────────────────────┘ │ ─ │ │ ↕ Margin ├──────────────────────────────────────────────────┬──────────┤ ─ │[start] [♠][♦][♣][♥] │en│ 12:00 │ └──────────────────────────────────────────────────┴──────────┘ │◄─►│ │◄─►│ Margin Margin * Note that this simple algorithm will always want to leave the cursor out of the window, therefor the window will jumps to its left: ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │ ▼-┌──────────────┐ │ ┌──────────────┐▼- │ │ │ Window [X]│ │ │ Window [X]│ │ │ ├──────────────┤ │ ├──────────────┤ │ │ │ ┌───┐ │ │ │ ┌───┐ │ │ │ │ Val: │ │ │ -> │ │ Val: │ │ │ │ │ │ └───┘ │ │ │ └───┘ │ │ │ └──────────────┘ │ └──────────────┘ │ │ │ │ │ ├──────────────────────┬──────────┤ ├──────────────────────┬──────────┤ │[start] [♠][♦][♣] │en│ 12:00 │ │[start] [♠][♦][♣] │en│ 12:00 │ └──────────────────────┴──────────┘ └──────────────────────┴──────────┘ If this is not a requirement, you can add a parameter to just use the margin: ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │ ▼-┌──────────────┐ │ ┌─▼-───────────┐ │ │ │ Window [X]│ │ │ Window [X]│ │ │ ├──────────────┤ │ ├──────────────┤ │ │ │ ┌───┐ │ │ │ ┌───┐ │ │ │ │ Val: │ │ │ -> │ │ Val: │ │ │ │ │ │ └───┘ │ │ │ └───┘ │ │ │ └──────────────┘ │ └──────────────┘ │ │ │ │ │ ├──────────────────────┬──────────┤ ├──────────────────────┬──────────┤ │[start] [♠][♦][♣] │en│ 12:00 │ │[start] [♠][♦][♣] │en│ 12:00 │ └──────────────────────┴──────────┘ └──────────────────────┴──────────┘ * Supports also the following scenarios: 1) Screen over screen: ┌─────────────────┐ │ │ │ │ │ │ │ │ └─────────────────┘ ┌───────────────────┐ │ │ │ ▼- │ │ │ │ │ │ │ └──────┬─────┬──────┘ ─┴─────┴─ 2) Window bigger than screen hight or width ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │ │ │ ┌──────────────┐ │ │ │ │ │ Window [X]│ │ │ ▼-┌────────────│─┐ │ ├──────────────┤ ▼- │ │ │ Window [│]│ │ │ ┌───┐ │ │ │ ├────────────│─┤ -> │ │ Val: │ │ │ │ │ │ ┌───┐│ │ │ │ └───┘ │ │ │ │ Val: │ ││ │ │ │ ┌───┐ │ │ │ │ └───┘│ │ │ │ Val: │ │ │ │ ├──────────────────────┬──────────┤ │ ├──────────────────────┬──────────┤ │[start] [♠][♦][♣] │en│ 12:00 │ │ │[start] [♠][♦][♣] │en│ 12:00 │ └──────────────────────┴──────────┘ │ └──────────────────────┴──────────┘ │ ┌───┐ │ │ └───┘ │ │ Val: │ │ │ └──────────────┘ │ └───┘ │ └──────────────┘ ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │ │ │ │ │ │ │ ┌───────────────────────────────│───┐ │ ▼-┌──────────────────────────│────────┐ │ │ W▼-dow │[X]│ │ │ Window │ [X]│ │ ├───────────────────────────────│───┤ │ ├──────────────────────────│────────┤ │ │ ┌───┐ ┌───┐ ┌─┤─┐ │ │ │ ┌───┐ ┌───┐ │ ┌───┐ │ -> │ │ Val: │ │ Val: │ │ Val: │ │ │ │ │ │ Val: │ │ Val: │ │ Va│: │ │ │ │ │ └───┘ └───┘ └─┤─┘ │ │ │ └───┘ └───┘ │ └───┘ │ │ └───────────────────────────────│───┘ ├──────────────────────┬──────────┤────────┘ ├──────────────────────┬──────────┤ │[start] [♠][♦][♣] │en│ 12:00 │ │[start] [♠][♦][♣] │en│ 12:00 │ └──────────────────────┴──────────┘ └──────────────────────┴──────────┘
<remark><code>...</code></remark>
fuente
Entiendo las demandas. La cuestión es que existen métodos WPF para obtener esos valores, pero sí, uno de los contribuyentes tiene razón, no directamente. La solución no es obtener todas esas soluciones, sino cambiar el enfoque inicial de acuerdo con un diseño y desarrollo limpios.
A) Configure la ventana principal inicial en pantalla
B) Obtenga los valores para ActualWindow que incluyen una tonelada de métodos útiles de WPF
C) Puede agregar tantas ventanas como desee para el comportamiento que desea tener, como redimensionable, minimizado lo que sea ... pero ahora siempre puede acceder a la pantalla cargada y renderizada
Tenga cuidado con el siguiente ejemplo, hay un código que hace que sea necesario usar ese tipo de enfoque, sin embargo, debería funcionar (le daría los puntos para cada una de las esquinas de su pantalla): Ejemplo de trabajo en una sola, Monitor dual y diferentes resoluciones (dentro de la clase de ventana principal Primal):
InitializeComponent(); […] ActualWindow.AddHandler(Window.LoadedEvent, new RoutedEventHandler(StartUpScreenLoaded));
Evento enrutado:
private void StartUpScreenLoaded(object sender, RoutedEventArgs e) { Window StartUpScreen = sender as Window; // Dispatcher Format B: Dispatcher.Invoke(new Action(() => { // Get Actual Window on Loaded StartUpScreen.InvalidateVisual(); System.Windows.Point CoordinatesTopRight = StartUpScreen.TranslatePoint(new System.Windows.Point((StartUpScreen.ActualWidth), (0d)), ActualWindow); System.Windows.Point CoordinatesBottomRight = StartUpScreen.TranslatePoint(new System.Windows.Point((StartUpScreen.ActualWidth), (StartUpScreen.ActualHeight)), ActualWindow); System.Windows.Point CoordinatesBottomLeft = StartUpScreen.TranslatePoint(new System.Windows.Point((0d), (StartUpScreen.ActualHeight)), ActualWindow); // Set the Canvas Top Right, Bottom Right, Bottom Left Coordinates System.Windows.Application.Current.Resources["StartUpScreenPointTopRight"] = CoordinatesTopRight; System.Windows.Application.Current.Resources["StartUpScreenPointBottomRight"] = CoordinatesBottomRight; System.Windows.Application.Current.Resources["StartUpScreenPointBottomLeft"] = CoordinatesBottomLeft; }), DispatcherPriority.Loaded); }
fuente
Si usa cualquier ventana de pantalla completa (que la tenga
WindowState = WindowState.Maximized, WindowStyle = WindowStyle.None
), puede ajustar su contenidoSystem.Windows.Controls.Canvas
así:<Canvas Name="MyCanvas" Width="auto" Height="auto"> ... </Canvas>
Luego puede usar
MyCanvas.ActualWidth
yMyCanvas.ActualHeight
para obtener la resolución de la pantalla actual, teniendo en cuenta la configuración de DPI y en unidades independientes del dispositivo. No agrega márgenes como lo hace la ventana maximizada.(Canvas acepta mensajes de correo
UIElement
electrónico como elementos secundarios, por lo que debería poder usarlo con cualquier contenido).fuente
Center Window en la pantalla en XAML y
WindowStartupLocation="CenterOwner"
luego llamar en WindowLoaded ()double ScreenHeight = 2 * (Top + 0.5 * Height);
fuente
double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth; double screenhight= System.Windows.SystemParameters.PrimaryScreenHeight;
fuente
Funciona con
this.Width = System.Windows.SystemParameters.VirtualScreenWidth; this.Height = System.Windows.SystemParameters.VirtualScreenHeight;
Probado en 2 monitores.
fuente
VirtualScreen
abarca todas las pantallas, ¡así que esto nunca funcionará si tienes más de una pantalla!