Как получить размер текущего экрана в WPF? - PullRequest
76 голосов
/ 18 декабря 2009

Я знаю, что могу получить размер основного экрана, используя

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

а как узнать размер текущего экрана? (Пользователи с несколькими экранами не всегда используют основной экран, и не все экраны используют одинаковое разрешение, верно?)

Было бы неплохо получить доступ к размеру из XAML, но этого было бы достаточно из кода (C #).

Ответы [ 10 ]

68 голосов
/ 22 января 2010

Я создал небольшую обертку вокруг экрана из System.Windows.Forms, в настоящее время все работает ... Не уверен насчет «независимых от устройства пикселей».

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; }
    }
}
18 голосов
/ 09 сентября 2013

Здесь, приятель. Это даст вам только ширину и высоту рабочей зоны

System.Windows.SystemParameters.WorkArea.Width
System.Windows.SystemParameters.WorkArea.Height
12 голосов
/ 18 декабря 2009

Насколько я знаю, нет встроенной функции WPF для получения размеров текущего монитора.Вместо этого вы можете PInvoke встроить функции нескольких мониторов дисплея , обернуть их в управляемый класс и предоставить все свойства, необходимые для их использования из XAML.

6 голосов
/ 10 марта 2014

Это даст вам текущий экран в левом верхнем углу окна, просто вызовите this.CurrentScreen () для получения информации о текущем экране.

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));
         }
     }
}
5 голосов
/ 18 мая 2010

Потратьте время на сканирование членов SystemParameters.

  • VirtualScreenWidth
  • VirtualScreenHeight

Они даже учитывают относительные положения экранов.

Проверено только с двумя мониторами.

3 голосов
/ 24 декабря 2016

Если вы знакомы с использованием класса System.Windows.Forms , тогда вы можете просто добавить ссылку класса System.Windows.Forms в свой проект:

Обозреватель решений -> Ссылки -> Добавить ссылки ... -> (Сборки: Framework) -> прокрутить вниз и проверьте System.Windows.Forms сборка -> OK .

Теперь вы можете добавить с помощью выражения System.Windows.Forms; и использовать экран в своем проекте wpf, как и раньше.

1 голос
/ 15 декабря 2016

Почему бы просто не использовать это?

var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow);
var activeScreen = Screen.FromHandle(interopHelper.Handle);
0 голосов
/ 07 мая 2019

Я понимаю требования. Дело в том, что есть методы WPF для получения этих значений - но да, один из авторов прав, а не напрямую. Решение состоит не в том, чтобы обойти все эти обходные пути, а в том, чтобы изменить первоначальный подход в соответствии с принципами чистого проектирования и разработки.

A) Установите начальное главное окно на экран

B) Получить значения для ActualWindow, включая массу полезных методов WPF

C) Вы можете добавить столько Windows, сколько вам нужно, для поведения, которое вы хотите иметь, например, изменение размера, сворачивание чего угодно ... но теперь вы всегда можете получить доступ к загруженному и отображаемому экрану

Пожалуйста, будьте осторожны со следующим примером: вокруг есть некоторый Кодекс, который делает необходимым использование такого подхода, однако он должен работать (он даст вам очки за каждый из углов вашего экрана): Рабочий пример для одного, двух мониторов и разных разрешений (в пределах класса основного основного окна):

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

перенаправленное событие:

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);
    }
0 голосов
/ 21 марта 2016

Работает с

this.Width = System.Windows.SystemParameters.VirtualScreenWidth;
this.Height = System.Windows.SystemParameters.VirtualScreenHeight;

Проверено на 2 мониторах.

0 голосов
/ 14 ноября 2013
double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
double screenhight= System.Windows.SystemParameters.PrimaryScreenHeight;
...