web-dev-qa-db-fra.com

Comment obtenir la taille de l'écran actuel dans WPF?

Je sais que je peux obtenir la taille de l'écran principal en utilisant

System.Windows.SystemParameters.PrimaryScreenWidth;
System.Windows.SystemParameters.PrimaryScreenHeight;

Mais comment puis-je 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, n'est-ce pas?)

Ce serait bien de pouvoir accéder à la taille à partir de XAML, mais cela depuis le code (C #) suffirait.

77
Nils

Autant que je sache, il n’existe pas de fonction WPF native permettant d’obtenir des dimensions du moniteur actuel. Au lieu de cela, vous pouvez utiliser PInvoke natif plusieurs fonctions de moniteur d’affichage , les envelopper dans une classe gérée et exposer toutes les propriétés dont vous avez besoin pour les utiliser à partir de XAML.

12
Anvaka

J'ai créé un petit wrapper autour de l'écran à partir de System.Windows.Forms, tout fonctionne actuellement ... 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; }
    }
}
69
Nils

Ici mon pote. Cela vous donnera seulement la largeur et la hauteur de la zone de travail

System.Windows.SystemParameters.WorkArea.Width
System.Windows.SystemParameters.WorkArea.Height
19
Guilherme Ferreira

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));
         }
     }
}
6
E.J.

Prenez le temps d'analyser les membres SystemParameters.

  • VirtualScreenWidth
  • VirtualScreenHeight

Celles-ci prennent même en compte les positions relatives des écrans.

Seulement testé avec deux moniteurs.

5
dana

Si vous maîtrisez 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) -> faire défiler down et vérifiez System.Windows.Forms Assembly -> OK .

Vous pouvez maintenant ajouter à l'aide de System.Windows.Forms; et utiliser screen dans votre projet wpf comme auparavant.

3
Phương Trần

Je comprends les demandes. Le problème, c’est qu’il existe des méthodes WPF pour obtenir ces valeurs - mais oui, l’un des contributeurs a raison, pas directement. La solution ne consiste pas à obtenir toutes ces solutions de contournement, mais à modifier l'approche initiale en fonction d'une conception et d'un développement propres.

A) Définir la fenêtre principale initiale à l'écran

B) Obtenez les valeurs de la fenêtre ActualWindow, y compris une tonne de méthodes WPF utiles

C) Vous pouvez ajouter autant de Windows que vous le souhaitez pour le comportement que vous souhaitez, comme redimensionner, minimiser… mais maintenant, vous pouvez toujours accéder à l'écran chargé et rendu.

Veuillez faire attention à l'exemple suivant, il existe un code qui rend nécessaire l'utilisation de ce type d'approche, mais cela devrait fonctionner (cela vous donnerait les points pour chacun des coins de votre écran): Exemple de travail sur Single, Double moniteur et différentes résolutions (dans la classe de fenêtre principale Primal):

InitializeComponent();
[…]
ActualWindow.AddHandler(Window.LoadedEvent, new RoutedEventHandler(StartUpScreenLoaded));

Evénement routé:

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

Pourquoi ne pas simplement utiliser ceci?

var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow);
var activeScreen = Screen.FromHandle(interopHelper.Handle);
1
Matteo Zilio

Centrez la fenêtre sur l’écran en XAML WindowStartupLocation="CenterOwner" Puis appelez WindowLoaded ()

double ScreenHeight = 2 * (Top + 0.5 * Height);

0
mikesl