代码之家  ›  专栏  ›  技术社区  ›  Nils

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

  •  69
  • Nils  · 技术社区  · 15 年前

    我知道我可以通过使用

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

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

    9 回复  |  直到 8 年前
        1
  •  15
  •   Anvaka    15 年前

    据我所知,没有本机WPF函数来获取当前监视器的维度。相反,你可以选择平沃克本地人 multiple display monitors functions

        2
  •  78
  •   Nils    11 年前

    不过,不确定“设备独立像素”。

    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
  •  27
  •   Guilherme Ferreira    11 年前

    这是布迪。这将只提供工作区的宽度和高度

    System.Windows.SystemParameters.WorkArea.Width
    System.Windows.SystemParameters.WorkArea.Height
    
        4
  •  17
  •   E.J.    10 年前

    这将根据窗口左上角显示当前屏幕,只需调用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
  •  9
  •   Juv    4 年前

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

    我使用它来重新定位一个窗口,窗口从右向下打开到鼠标所在的位置。由于窗口相当大,在许多情况下,它超出了屏幕范围。以下代码基于@e-j answer: This will give you the current screen...

    守则:

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

    一些解释:

    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 │     
         └──────────────────────┴──────────┘             └──────────────────────┴──────────┘     
    
    • 我别无选择,只能使用代码格式(否则为空格)
    • <remark><code>...</code></remark>
        6
  •  5
  •   Joe Mayo    4 年前

    花点时间浏览SystemParameters成员。

    • VirtualScreenWidth
    • VirtualScreenHeight

    仅使用两台监视器进行测试。

        7
  •  3
  •   Matteoz    8 年前

    为什么不用这个?

    var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow);
    var activeScreen = Screen.FromHandle(interopHelper.Handle);
    
        8
  •  3
  •   PhÆ°Æ¡ng Trần    8 年前

    如果您熟悉使用 System.Windows.Forms 添加引用 将System.Windows.Forms类添加到项目中:

    解决方案管理器 工具书类 添加引用。。。 -&燃气轮机;向下滚动并检查 System.Windows.Forms 装配-> 好啊 .

    现在您可以添加 使用System.Windows.Forms; 和以前一样,在wpf项目中使用语句和屏幕。

        9
  •  1
  •   slfan Narendra    5 年前

    我理解这些要求。 解决方案不是获得所有这些变通方法,而是根据干净的设计和开发更改初始方法。

    A) 将初始主窗口设置为屏幕

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

    请注意下面的示例,有一些代码使得有必要使用这种方法,但是它应该是有效的(它会给你屏幕每个角落的分数):

    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);
        }
    
        10
  •  1
  •   zvizesna    5 年前

    如果您使用任何全屏窗口(具有 WindowState = WindowState.Maximized, WindowStyle = WindowStyle.None ),您可以将其内容包装为 System.Windows.Controls.Canvas 这样地:

    <Canvas Name="MyCanvas" Width="auto" Height="auto">
    ...
    </Canvas>
    

    然后你可以用 MyCanvas.ActualWidth MyCanvas.ActualHeight 要获得当前屏幕的分辨率,请将DPI设置考虑在内,并以独立于设备的单位显示。 它不会像最大化窗口本身那样添加任何边距。

    (画布接受 UIElement s作为儿童,因此您应该能够将其用于任何内容。)

        11
  •  1
  •   tstephansen    4 年前

    我偶然看到这篇文章,发现没有一个答案完全抓住了我想做的事情。我有一台分辨率为3840x2160的笔记本电脑和两台分辨率为1920x1080的显示器。为了在WPF应用程序中获得正确的监视器大小,我必须 make the application DPI aware . 然后,我使用Win32 API获取监视器大小。

    为此,我首先将窗口移动到我想从中获取大小的显示器上。然后通过获取应用程序主窗口的hwnd(不一定是主窗口,但我的应用程序只有一个窗口)和一个IntPtr到监视器。然后,我创建了MonitorInfo结构的一个新实例,并调用了GetMonitorInfo方法。

    MonitorInfo结构具有工作区域和屏幕的完整分辨率,因此您可以返回所需的任何一个。这还允许您省去对System.Windows.Forms的引用(假设您在应用程序中不需要它)。我使用了.NET框架 Reference Source 以便System.Windows.Forms.Screen提供此解决方案。

    public System.Drawing.Size GetMonitorSize()
    {
        var window = System.Windows.Application.Current.MainWindow;
        var hwnd = new WindowInteropHelper(window).EnsureHandle();
        var monitor = NativeMethods.MonitorFromWindow(hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST);
        NativeMethods.MONITORINFO info = new NativeMethods.MONITORINFO();
        NativeMethods.GetMonitorInfo(new HandleRef(null, monitor), info);
        return info.rcMonitor.Size;
    }
    
    internal static class NativeMethods
    {
        public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;
    
        [DllImport("user32.dll")]
        public static extern IntPtr MonitorFromWindow(IntPtr handle, Int32 flags);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetMonitorInfo(HandleRef hmonitor, MONITORINFO info);
        
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
        public class MONITORINFO
        {
            internal int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
            internal RECT rcMonitor = new RECT();
            internal RECT rcWork = new RECT();
            internal int dwFlags = 0;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
    
            public RECT(int left, int top, int right, int bottom)
            {
                this.left = left;
                this.top = top;
                this.right = right;
                this.bottom = bottom;
            }
    
            public RECT(System.Drawing.Rectangle r)
            {
                left = r.Left;
                top = r.Top;
                right = r.Right;
                bottom = r.Bottom;
            }
    
            public static RECT FromXYWH(int x, int y, int width, int height) => new RECT(x, y, x + width, y + height);
    
            public System.Drawing.Size Size => new System.Drawing.Size(right - left, bottom - top);
        }
    }
    
        12
  •  1
  •   stoj    3 年前

    我理解这是一个老问题,但鉴于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};
            }
        }
    }
    
        13
  •  -1
  •   mikesl    5 年前

    在XAML中居中显示屏幕上的窗口 WindowStartupLocation="CenterOwner"

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

        14
  •  -4
  •   Afzaal Ahmad Zeeshan    10 年前
    double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
    double screenhight= System.Windows.SystemParameters.PrimaryScreenHeight;
    
        15
  •  -4
  •   Dovydas Å opa Venkatesh    8 年前

    它与

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

    在2台监视器上测试。