Je sais que je peux obtenir la taille de l'écran principal en utilisant
System.Windows.SystemParameters.PrimaryScreenWidth;
System.Windows.SystemParameters.PrimaryScreenHeight;
Mais comment obtenir la taille de l'écran actuel? (Les utilisateurs multi-écrans n'utilisent pas toujours l'écran principal et tous les écrans n'utilisent pas la même résolution, non?)
Ce serait bien de pouvoir accéder à la taille à partir de XAML, mais le faire à partir du code (C #) suffirait.
Réponses:
Pour autant que je sache, il n'y a pas de fonction WPF native pour obtenir les dimensions du moniteur actuel. Au lieu de cela, vous pouvez PInvoke des fonctions natives de plusieurs moniteurs d'affichage, les encapsuler dans une classe gérée et exposer toutes les propriétés dont vous avez besoin pour les consommer à partir de XAML.
la source
J'ai créé un petit wrapper autour de l'écran à partir de System.Windows.Forms, actuellement tout fonctionne ... Je ne suis pas sûr des "pixels indépendants du périphérique", cependant.
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; } } }
la source
Ici mon pote. Cela ne vous donnera que la largeur et la hauteur de la zone de travail
System.Windows.SystemParameters.WorkArea.Width System.Windows.SystemParameters.WorkArea.Height
la source
Cela vous donnera l'écran actuel basé sur le coin supérieur gauche de la fenêtre, appelez simplement this.CurrentScreen () pour obtenir des informations sur l'écran actuel.
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)); } } }
la source
Prenez le temps de parcourir les membres SystemParameters.
VirtualScreenWidth
VirtualScreenHeight
Celles-ci prennent même en compte les positions relatives des écrans.
Testé uniquement avec deux moniteurs.
la source
Pourquoi ne pas simplement l'utiliser?
var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow); var activeScreen = Screen.FromHandle(interopHelper.Handle);
la source
System.Windows.Forms.Screen
pour faire face au pixel indépendant de l'appareilSi vous êtes familiarisé avec l'utilisation de la classe System.Windows.Forms , vous pouvez simplement ajouter une référence de la classe System.Windows.Forms à votre projet:
Explorateur de solutions -> Références -> Ajouter des références ... -> (Assemblies: Framework) -> faites défiler vers le bas et vérifiez l' assembly System.Windows.Forms -> OK .
Vous pouvez maintenant ajouter en utilisant System.Windows.Forms; et utilisez screen dans votre projet wpf comme avant.
la source
J'avais également besoin de la dimension actuelle de l'écran, en particulier de la zone de travail, qui renvoyait le rectangle à l'exclusion de la largeur de la barre des tâches.
Je l'ai utilisé pour repositionner une fenêtre, qui est ouverte vers la droite et vers le bas là où la souris est positionnée. Comme la fenêtre est assez grande, dans de nombreux cas, elle est sortie des limites de l'écran. Le code suivant est basé sur @ej Réponse: Cela vous donnera l'écran en cours ... . La différence est que je montre également mon algorithme de repositionnement, qui, je suppose, est en fait le point.
Le code:
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; } } }
Quelques explications:
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>
la source
Je comprends les demandes. Le fait est qu'il existe des méthodes WPF pour obtenir ces valeurs - mais oui, l'un des contributeurs a raison, pas directement. La solution n'est pas d'obtenir toutes ces solutions de contournement, mais de changer l'approche initiale selon une conception et un développement propres.
A) Réglez la fenêtre principale initiale sur Écran
B) Obtenez les valeurs pour ActualWindow, y compris une tonne de méthodes WPF utiles
C) Vous pouvez ajouter autant de fenêtres que vous le souhaitez pour le comportement que vous souhaitez avoir, comme redimensionnable, minimisé quoi que ce soit ... mais maintenant vous pouvez toujours accéder à l'écran chargé et rendu
Veuillez faire attention à l'exemple suivant, il y a du code autour qui rend nécessaire d'utiliser ce type d'approche, mais cela devrait fonctionner (cela vous donnerait les points pour chacun des coins de votre écran): Exemple de travail sur simple, Double moniteur et différentes résolutions (dans la classe principale de la fenêtre principale):
InitializeComponent(); […] ActualWindow.AddHandler(Window.LoadedEvent, new RoutedEventHandler(StartUpScreenLoaded));
Événement acheminé:
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); }
la source
Si vous utilisez une fenêtre plein écran (ayant son
WindowState = WindowState.Maximized, WindowStyle = WindowStyle.None
), vous pouvez envelopper son contenuSystem.Windows.Controls.Canvas
comme ceci:<Canvas Name="MyCanvas" Width="auto" Height="auto"> ... </Canvas>
Ensuite, vous pouvez utiliser
MyCanvas.ActualWidth
etMyCanvas.ActualHeight
pour obtenir la résolution de l'écran actuel, avec les paramètres DPI pris en compte et en unités indépendantes de l'appareil. Il n'ajoute aucune marge comme le fait la fenêtre agrandie elle-même.(Canvas accepte les
UIElement
s comme enfants, vous devriez donc pouvoir l'utiliser avec n'importe quel contenu.)la source
Centrer la fenêtre sur l'écran en XAML
WindowStartupLocation="CenterOwner"
puis appeler WindowLoaded ()double ScreenHeight = 2 * (Top + 0.5 * Height);
la source
double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth; double screenhight= System.Windows.SystemParameters.PrimaryScreenHeight;
la source
Cela fonctionne avec
this.Width = System.Windows.SystemParameters.VirtualScreenWidth; this.Height = System.Windows.SystemParameters.VirtualScreenHeight;
Testé sur 2 moniteurs.
la source
VirtualScreen
s'étend sur tous les écrans - donc cela ne fonctionnera jamais si vous avez plus d'un écran!