your programing

WPF에서 현재 화면의 크기를 얻는 방법은 무엇입니까?

lovepro 2020. 10. 10. 10:47
반응형

WPF에서 현재 화면의 크기를 얻는 방법은 무엇입니까?


사용하여 기본 화면의 크기를 얻을 수 있다는 것을 알고 있습니다.

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

하지만 현재 화면의 크기를 어떻게 알 수 있습니까? (멀티 스크린 사용자가 항상 기본 화면을 사용하는 것은 아니며 모든 화면이 동일한 해상도를 사용하는 것은 아닙니다.)

XAML에서 크기에 액세스 할 수 있으면 좋겠지 만 코드 (C #)로도 충분합니다.


내가 아는 한 현재 모니터의 크기를 가져 오는 기본 WPF 함수는 없습니다. 대신 네이티브 다중 디스플레이 모니터 함수를 PInvoke 하고 관리되는 클래스로 래핑하고 XAML에서 사용하는 데 필요한 모든 속성을 노출 할 수 있습니다.


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

Here budy. This will give you only the width and height of the workarea

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

This will give you the current screen based on the top left of the window just call this.CurrentScreen() to get info on the current screen.

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

Take the time to scan through the SystemParameters members.

  • VirtualScreenWidth
  • VirtualScreenHeight

These even take into account the relative positions of the screens.

Only tested with two monitors.


If you are familiar with using System.Windows.Forms class then you can just add a reference of System.Windows.Forms class to your project:

Solution Explorer -> References -> Add References... -> ( Assemblies : Framework ) -> scroll down and check System.Windows.Forms assembly -> OK.

Now you can add using System.Windows.Forms; statement and use screen in your wpf project just like before.


Why not just use this?

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

I understand the demands. The thing is, there are WPF Methods for getting those values - but yes, one of the contributors is right, not directly. The Solution is not to get all those workarounds, but to change the initial approach according to clean Design and Development.

A) Set the initial Main Window to Screen

B) Get the Values for the ActualWindow including a ton of useful WPF Methods

C) You can add as many Windows as you like for the behaviour you want to have, like resizeable, minimized whatever… but now you always can access the Loaded and Rendered Screen

Please be careful with the following example, there is some Code around that makes it necessary to use that kind of approach, however it should work (It would give you the Points for each of the Corners of your Screen): Working Example on Single, Dual Monitor and different Resolutions (Within the Primal Main Window Class):

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

Routed Event:

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

Center Window on the screen in XAML WindowStartupLocation="CenterOwner" then call in WindowLoaded()

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


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

It works with

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

Tested on 2 monitors.

참고URL : https://stackoverflow.com/questions/1927540/how-to-get-the-size-of-the-current-screen-in-wpf

반응형