Как получить размер текущего экрана в WPF?

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

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

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

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

Ответ 1

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

Ответ 2

Я создал небольшую обертку вокруг экрана из 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; }
    }
}

Ответ 3

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

System.Windows.SystemParameters.WorkArea.Width
System.Windows.SystemParameters.WorkArea.Height

Ответ 4

Это даст вам текущий экран, основанный на верхнем левом углу окна, просто вызовите 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

Найдите время, чтобы просмотреть элементы SystemParameters.

  • VirtualScreenWidth
  • VirtualScreenHeight

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

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

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

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

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

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

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

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

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

Ответ 9

Центрировать окно на экране в XAML WindowStartupLocation="CenterOwner", затем вызвать WindowLoaded()

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

Ответ 10

double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
double screenhight= System.Windows.SystemParameters.PrimaryScreenHeight;

Ответ 11

Он работает с

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

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