C# 如何在WPF中获取当前屏幕的大小?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1927540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:55:29  来源:igfitidea点击:

How to get the size of the current screen in WPF?

c#wpfxamlsizescreen

提问by Nils

I know I can get the size of the primary screen by using

我知道我可以通过使用获得主屏幕的大小

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

But how do I get the size of the current screen? (Multi-Screen users do not always use the primary screen and not all screens are using the same resolution, right?)

但是我如何获得当前屏幕的大小?(多屏用户并不总是使用主屏幕,也不是所有屏幕都使用相同的分辨率,对吗?)

It would be nice to be able to acces the size from XAML, but doing so from code (C#) would suffice.

能够从 XAML 访问大小会很好,但是从代码 (C#) 这样做就足够了。

采纳答案by Anvaka

As far as I know there is no native WPF function to get dimensions of the current monitor. Instead you could PInvoke native multiple display monitors functions, wrap them in managed class and expose all properties you need to consume them from XAML.

据我所知,没有本机 WPF 函数来获取当前监视器的尺寸。相反,您可以 PInvoke 本机多显示监视器功能,将它们包装在托管类中,并公开从 XAML 使用它们所需的所有属性。

回答by Nils

I created a little wrapper around the Screen from System.Windows.Forms, currently everything works... Not sure about the "device independent pixels", though.

我在 System.Windows.Forms 的 Screen 周围创建了一个小包装器,目前一切正常......不过不确定“设备独立像素”。

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

回答by dana

Take the time to scan through the SystemParameters members.

花点时间浏览一下 SystemParameters 成员。

  • VirtualScreenWidth
  • VirtualScreenHeight
  • 虚拟屏幕宽度
  • 虚拟屏幕高度

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

这些甚至考虑了屏幕的相对位置。

Only tested with two monitors.

仅使用两台显示器进行测试。

回答by Guilherme Ferreira

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

在这里,伙计。这只会给你工作区的宽度和高度

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

回答by Rahul chalkhure

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

回答by E.J.

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.

这将为您提供基于窗口左上角的当前屏幕,只需调用 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));
         }
     }
}

回答by Hoang

It works with

它与

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

Tested on 2 monitors.

在 2 台显示器上测试。

回答by Matteo Zilio

Why not just use this?

为什么不直接使用这个?

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

回答by Ph??ng Tra?n

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

如果您熟悉使用System.Windows.Forms类,那么您可以System.Windows.Forms 类的引用添加到您的项目中:

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

解决方案资源管理器->引用->添加引用...-> (程序集:框架)-> 向下滚动并检查System.Windows.Forms程序集->确定

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

现在您可以使用 System.Windows.Forms添加像以前一样在 wpf 项目中声明和使用 screen 。

回答by Dororo

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.

我理解这些要求。问题是,有 WPF 方法可以获取这些值 - 但是是的,其中一位贡献者是对的,而不是直接的。解决方案不是获得所有这些变通方法,而是根据干净的设计和开发更改初始方法。

A) Set the initial Main Window to Screen

A) 将初始主窗口设置为 Screen

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

B) 获取 ActualWindow 的值,包括大量有用的 WPF 方法

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

C) 您可以为您想要的行为添加任意数量的窗口,例如可调整大小、最小化任何内容……但现在您始终可以访问加载和渲染屏幕

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