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

Nil*_*ils 79 c# size wpf xaml screen

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

System.Windows.SystemParameters.PrimaryScreenWidth;
System.Windows.SystemParameters.PrimaryScreenHeight;
Run Code Online (Sandbox Code Playgroud)

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

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

Nil*_*ils 68

我从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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 效果很好.我只是扩展了GetRect方法以返回设备独立像素中的Rect:private Rect GetRect(Rectangle value){var pixelWidthFactor = SystemParameters.WorkArea.Width/this.screen.WorkingArea.Width; var pixelHeightFactor = SystemParameters.WorkArea.Height/this.screen.WorkingArea.Height; 返回new Rect {X = value.X*pixelWidthFactor,Y = value.Y*pixelHeightFactor,Width = value.Width*pixelWidthFactor,Height = value.Height*pixelHeightFactor}; } (4认同)
  • @Jürgen:我相信你的方法只适用于非常特殊的情况.如果"this.screen"具有与主显示器不同的宽高比(您的方法始终用作参考而不是当前显示器),则您将错误地获得宽度和高度的不同比例因子,从而导致错误的屏幕尺寸.如果当前屏幕具有与主屏幕不同的DPI设置,则边界将全部错误.在我的系统上,返回的Rect的每个值都(非常)不正确. (2认同)

Gui*_*ira 22

在这里budy.这将只给出工作区的宽度和高度

System.Windows.SystemParameters.WorkArea.Width
System.Windows.SystemParameters.WorkArea.Height
Run Code Online (Sandbox Code Playgroud)

  • "获取主显示器监视器上工作区的大小." - 不是我想要的...... (7认同)
  • ..但那正是我想要的,谢谢! (2认同)

Anv*_*aka 13

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


sto*_*toj 12

我很欣赏这是一个老问题,但由于 WPF 仍然没有提供一种“开箱即用”的好方法,并且上面的答案似乎有点过于复杂,希望您会发现下面的解决方案更容易一些消化..

  • WPF 友好,即返回与设备无关的单位(不是 WinForm 样式像素)
  • 支持不同 DPI 的显示器
  • 适合任何尺寸/位置的任务栏
  • System.Windows.Window 上的扩展方法。

享受 :)

using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using Point = System.Drawing.Point;

namespace ClrVpin.Shared
{
    public static class WindowExtensions
    {
        public static Rect GetCurrentScreenWorkArea(this Window window)
        {
            var screen = Screen.FromPoint(new Point((int) window.Left, (int) window.Top));
            var dpiScale = VisualTreeHelper.GetDpi(window);

            return new Rect {Width = screen.WorkingArea.Width / dpiScale.DpiScaleX, Height = screen.WorkingArea.Height / dpiScale.DpiScaleY};
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Juv*_*Juv 9

我还需要当前的屏幕尺寸,特别是工作区,它返回不包括任务栏宽度的矩形。

我用它来重新定位一个窗口,该窗口向右和向下打开到鼠标所在的位置。由于窗口相当大,在许多情况下它超出了屏幕边界。下面的代码是基于@ej答案:这会给你当前屏幕...。不同之处在于我还展示了我的重新定位算法,我认为这实际上是重点。

编码:

using System.Windows;
using System.Windows.Forms;

namespace MySample
{

    public class WindowPostion
    {
        /// <summary>
        /// This method adjust the window position to avoid from it going 
        /// out of screen bounds.
        /// </summary>
        /// <param name="topLeft">The requiered possition without its offset</param>
        /// <param name="maxSize">The max possible size of the window</param>
        /// <param name="offset">The offset of the topLeft postion</param>
        /// <param name="margin">The margin from the screen</param>
        /// <returns>The adjusted position of the window</returns>
        System.Drawing.Point Adjust(System.Drawing.Point topLeft, System.Drawing.Point maxSize, int offset, int margin)
        {
            Screen currentScreen = Screen.FromPoint(topLeft);
            System.Drawing.Rectangle rect = currentScreen.WorkingArea;

            // Set an offset from mouse position.
            topLeft.Offset(offset, offset);

            // Check if the window needs to go above the task bar, 
            // when the task bar shadows the HUD window.
            int totalHight = topLeft.Y + maxSize.Y + margin;

            if (totalHight > rect.Bottom)
            {
                topLeft.Y -= (totalHight - rect.Bottom);

                // If the screen dimensions exceed the hight of the window
                // set it just bellow the top bound.
                if (topLeft.Y < rect.Top)
                {
                    topLeft.Y = rect.Top + margin;
                }
            }

            int totalWidth = topLeft.X + maxSize.X + margin;
            // Check if the window needs to move to the left of the mouse, 
            // when the HUD exceeds the right window bounds.
            if (totalWidth > rect.Right)
            {
                // Since we already set an offset remove it and add the offset 
                // to the other side of the mouse (2x) in addition include the 
                // margin.
                topLeft.X -= (maxSize.X + (2 * offset + margin));

                // If the screen dimensions exceed the width of the window
                // don't exceed the left bound.
                if (topLeft.X < rect.Left)
                {
                    topLeft.X = rect.Left + margin;
                }
            }

            return topLeft;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

一些解释:

1) topLeft - position of the top left at the desktop (works                     
   for multi screens - with different aspect ratio).                            
            Screen1              Screen2                                        
        ?  ?????????????????????????????????????????? Screen3                   
        ?  ?                   ??                   ????????????????????  ?     
        ?  ?                   ??                   ??   ?-            ?  ?     
   1080 ?  ?                   ??                   ??                 ?  ?     
        ?  ?                   ??                   ??                 ?  ? 900 
        ?  ?                   ??                   ??                 ?  ?     
        ?  ?????????????????????????????????????????????????????????????  ?     
                 ?????????            ?????????            ????????             
           ?????????????????????????????????????????????????????????????        
                   1920                 1920                1440                
   If the mouse is in Screen3 a possible value might be:                        
   topLeft.X=4140 topLeft.Y=195                                                 
2) offset - the offset from the top left, one value for both                    
   X and Y directions.                                                          
3) maxSize - the maximal size of the window - including its                     
   size when it is expanded - from the following example                        
   we need maxSize.X = 200, maxSize.Y = 150 - To avoid the expansion            
   being out of bound.                                                          

   Non expanded window:                                                         
   ???????????????????????????????? ?                                           
   ? Window Name               [X]? ?                                           
   ???????????????????????????????? ?                                           
   ?         ???????????????????  ? ? 100                                       
   ?  Text1: ?                 ?  ? ?                                           
   ?         ???????????????????  ? ?                                           
   ?                         [?]  ? ?                                           
   ???????????????????????????????? ?                                           
   ????????????????????????????????                                             
                 200                                                            

   Expanded window:                                                             
   ???????????????????????????????? ?                                           
   ? Window Name               [X]? ?                                           
   ???????????????????????????????? ?                                           
   ?         ???????????????????  ? ?                                           
   ?  Text1: ?                 ?  ? ?                                           
   ?         ???????????????????  ? ? 150                                       
   ?                         [?]  ? ?                                           
   ?         ???????????????????  ? ?                                           
   ?  Text2: ?                 ?  ? ?                                           
   ?         ???????????????????  ? ?                                           
   ???????????????????????????????? ?                                           
   ????????????????????????????????                                             
                 200                                                            
4) margin - The distance the window should be from the screen                   
   work-area - Example:                                                          
   ??????????????????????????????????????????????????????????????? ?            
   ?                                                             ? ? Margin     
   ?                                                             ? ?            
   ?                                                             ?              
   ?                                                             ?              
   ?                                                             ?              
   ?                          ????????????????????????????????   ?              
   ?                          ? Window Name               [X]?   ?              
   ?                          ????????????????????????????????   ?              
   ?                          ?         ???????????????????  ?   ?              
   ?                          ?  Text1: ?                 ?  ?   ?              
   ?                          ?         ???????????????????  ?   ?              
   ?                          ?                         [?]  ?   ?              
   ?                          ?         ???????????????????  ?   ?              
   ?                          ?  Text2: ?                 ?  ?   ?              
   ?                          ?         ???????????????????  ?   ?              
   ?                          ????????????????????????????????   ? ?            
   ?                                                             ? ? Margin     
   ??????????????????????????????????????????????????????????????? ?            
   ?[start] [?][?][?][?]                              ?en? 12:00 ?              
   ???????????????????????????????????????????????????????????????              
   ?????                                                     ?????              
    Margin                                                    Margin            

* Note that this simple algorithm will always want to leave the cursor          
  out of the window, therefor the window will jumps to its left:                
  ???????????????????????????????????        ???????????????????????????????????
  ?                  ?-????????????????      ?  ?????????????????-             ?
  ?                    ? Window    [X]?      ?  ? Window    [X]?               ?
  ?                    ????????????????      ?  ????????????????               ?
  ?                    ?       ?????  ?      ?  ?       ?????  ?               ?
  ?                    ?  Val: ?   ?  ? ->   ?  ?  Val: ?   ?  ?               ?
  ?                    ?       ?????  ?      ?  ?       ?????  ?               ?
  ?                    ????????????????      ?  ????????????????               ?
  ?                                 ?        ?                                 ?
  ???????????????????????????????????        ???????????????????????????????????
  ?[start] [?][?][?]     ?en? 12:00 ?        ?[start] [?][?][?]     ?en? 12:00 ?
  ???????????????????????????????????        ???????????????????????????????????
  If this is not a requirement, you can add a parameter to just use             
  the margin:                                                                   
  ???????????????????????????????????        ???????????????????????????????????
  ?                  ?-????????????????      ?                ???-???????????? ?
  ?                    ? Window    [X]?      ?                ? Window    [X]? ?
  ?                    ????????????????      ?                ???????????????? ?
  ?                    ?       ?????  ?      ?                ?       ?????  ? ?
  ?                    ?  Val: ?   ?  ? ->   ?                ?  Val: ?   ?  ? ?
  ?                    ?       ?????  ?      ?                ?       ?????  ? ?
  ?                    ????????????????      ?                ???????????????? ?
  ?                                 ?        ?                                 ?
  ???????????????????????????????????        ???????????????????????????????????
  ?[start] [?][?][?]     ?en? 12:00 ?        ?[start] [?][?][?]     ?en? 12:00 ?
  ???????????????????????????????????        ???????????????????????????????????
* Supports also the following scenarios:
  1) Screen over screen:
       ???????????????????  
       ?                 ?
       ?                 ?
       ?                 ?
       ?                 ?
       ???????????????????
     ????????????????????? 
     ?                   ? 
     ?  ?-               ? 
     ?                   ? 
     ?                   ? 
     ?                   ? 
     ????????????????????? 
           ?????????       
  2) Window bigger than screen hight or width
     ???????????????????????????????????        ??????????????????????????????????? 
     ?                                 ?        ? ????????????????                ?
     ?                                 ?        ? ? Window    [X]?                ?
     ?                  ?-????????????????      ? ???????????????? ?-             ?
     ?                    ? Window    [?]?      ? ?       ?????  ?                ?
     ?                    ???????????????? ->   ? ?  Val: ?   ?  ?                ? 
     ?                    ?       ?????? ?      ? ?       ?????  ?                ?
     ?                    ?  Val: ?   ?? ?      ? ?       ?????  ?                ?
     ?                    ?       ?????? ?      ? ?  Val: ?   ?  ?                ?
     ??????????????????????????????????? ?      ???????????????????????????????????
     ?[start] [?][?][?]     ?en? 12:00 ? ?      ?[start] [?][?][?]     ?en? 12:00 ?
     ??????????????????????????????????? ?      ???????????????????????????????????
                          ?       ?????  ?        ?       ?????  ?
                          ?  Val: ?   ?  ?        ????????????????
                          ?       ?????  ?
                          ????????????????


     ???????????????????????????????????             ???????????????????????????????????     
     ?                                 ?             ?                                 ? 
     ?                                 ?             ? ?????????????????????????????????????
     ?    ?-?????????????????????????????????????    ? ? W?-dow                        ?[X]?
     ?      ? Window                   ?     [X]?    ? ?????????????????????????????????????
     ?      ?????????????????????????????????????    ? ?       ?????      ?????      ????? ?
     ?      ?       ?????      ?????   ?  ????? ? -> ? ?  Val: ?   ? Val: ?   ? Val: ? ? ? ?
     ?      ?  Val: ?   ? Val: ?   ? Va?: ?   ? ?    ? ?       ?????      ?????      ????? ?
     ?      ?       ?????      ?????   ?  ????? ?    ? ?????????????????????????????????????
     ????????????????????????????????????????????    ???????????????????????????????????
     ?[start] [?][?][?]     ?en? 12:00 ?             ?[start] [?][?][?]     ?en? 12:00 ?     
     ???????????????????????????????????             ???????????????????????????????????     
Run Code Online (Sandbox Code Playgroud)
  • 我别无选择,只能使用代码格式(否则空格会丢失)。
  • 最初这出现在上面的代码中 <remark><code>...</code></remark>

  • 那个插图真是……美丽!! (13认同)
  • 我认为你需要一枚金牌来解释和说明 (3认同)

E.J*_*.J. 6

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

  • 这将返回当前屏幕,基于您调用辅助函数的窗口的左上角位置.但根据我的答案得分,我必须对这个问题遗漏一些东西. (2认同)

小智 5

花点时间浏览SystemParameters成员.

  • VirtualScreenWidth
  • VirtualScreenHeight

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

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

  • dana - 我没有测试过这个,但VirtualScreen*没有返回所有屏幕的全尺寸? - 我特别需要一个屏幕的大小(当前窗口所在的屏幕). (8认同)

小智 5

为什么不直接使用这个呢?

var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow);
var activeScreen = Screen.FromHandle(interopHelper.Handle);
Run Code Online (Sandbox Code Playgroud)