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


87

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

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

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

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


1
"현재"를 정의하십시오. 창은 한 번에 둘 이상의 화면에있을 수 있습니다.
Jim Balter 2018

답변:


13

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


이것이 바로 제가 두려워했던 것입니다. P / Invoke 또는 System.Windows.Forms.Screen에 어떻게 든 액세스 할 필요가 있습니다. 그렇게 할 때 항상 "장치 독립 픽셀"을 계산해야합니다. 그래도 감사합니다.
Nils

예 ... 아마도 SystemParameters.ConvertPixel () 함수가 도움이 될 것입니다. 그것은 내부하지만 반사판은 상관하지 않습니다) ...
Anvaka

74

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

이 멋진 작은 래퍼에 감사드립니다. global :: Rect는 WPF 3.5와 함께 사용할 때 일반 Rect로 변환해야했습니다.
Andy Dent

1
나는 이것을 좋아한다. 물론 약간의 작업이 필요하지만 100 % 해결책을 찾을 수는 없습니다.
제프

4
잘 작동합니다. 장치 독립 픽셀로 Rect를 반환하도록 GetRect 메서드를 확장했습니다. private Rect GetRect (Rectangle value) {var pixelWidthFactor = SystemParameters.WorkArea.Width / this.screen.WorkingArea.Width; var pixelHeightFactor = SystemParameters.WorkArea.Height / this.screen.WorkingArea.Height; return new Rect {X = value.X * pixelWidthFactor, Y = value.Y * pixelHeightFactor, Width = value.Width * pixelWidthFactor, Height = value.Height * pixelHeightFactor}; }
위르겐 바이엘

1
@ JürgenBayer의 코드를 추가하면 답변이 더욱 향상 될 것입니다. 장치 독립 픽셀에 문제가 있었고 Jürgen의 코드가 문제를 해결했습니다. 둘 다 감사합니다.
Bruno V

3
@ Jürgen : 귀하의 방법은 매우 특정한 상황에서만 작동한다고 생각합니다. "this.screen"이 기본 모니터 (현재 모니터 대신 항상 참조로 사용하는 방법)와 다른 종횡비를 갖는 경우 너비와 높이에 대해 다른 배율 요소를 잘못 가져와 잘못된 화면 크기가 발생합니다. 현재 화면의 DPI 설정이 기본 화면과 다르면 경계가 모두 잘못됩니다. 내 시스템에서 반환 된 Rect의 모든 단일 값은 (매우) 정확하지 않습니다.
wilford 2017-06-23

27

여기 친구. 이것은 작업 영역의 너비와 높이 만 제공합니다.

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

13
"주 디스플레이 모니터의 작업 영역 크기를 가져옵니다." - 나는 .... 찾고 있었다하지 무엇을
닐스

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

사용자가 기본 화면이 아닌 현재 화면의 크기를 찾고 있습니다.
greggannicott 2014

3
그러면 도우미 함수를 호출 한 창의 왼쪽 상단 위치를 기준으로 현재 화면이 반환됩니다. 그러나 내 대답의 점수를 바탕으로이 질문에 뭔가 빠진 것이 분명합니다.
EJ

아마도 greggannicott은 다른 답변 중 하나에 자신의 의견을 게시하려고했을 것입니다.
Jim Balter 2018

@ jim-balter가 투표했습니다-실제로 이것은 여기에서 가장 좋은 대답입니다. 작업 영역을 가져오고 대화 상자가 경계를 초과하지 않는지 확인하기 위해 화면이 필요했습니다. 여기에 솔루션을 게시하겠습니다. 요점 답변에 대한 빠른 EJ에 대한 찬사.
Juv

^ 기괴한 코멘트.
Jim Balter

5

시간을내어 SystemParameters 멤버를 살펴보십시오.

  • VirtualScreenWidth
  • VirtualScreenHeight

이것은 심지어 스크린의 상대적인 위치를 고려합니다.

두 대의 모니터에서만 테스트되었습니다.


9
dana-테스트하지 않았지만 VirtualScreen *이 모든 화면의 전체 크기를 반환하지 않습니까? -특히 한 화면의 크기가 필요합니다 (현재 창이있는 화면).
Nils

1
VirtualScreen은 모든 화면의 크기를 참조하는 것 같습니다
Thomas

1
하나의 광산이 내 화면 4 개를 모두 합친 크기를 반환했습니다.
DJ van Wyk

3

왜 이것을 사용하지 않습니까?

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

Screen은 WPF가 아닌 Windows.Forms이지만 이것이 시작점입니다. 그 당시 사용했던 솔루션 ( stackoverflow.com/a/2118993/180156 ) 을 살펴보면 이것이 정확히 제가 한 일입니다. 그러나 System.Windows.Forms.Screen장치 독립 픽셀에 대처하기 위해 포장 했습니다
Nils

3

System.Windows.Forms 클래스 사용에 익숙하다면 System.Windows.Forms 클래스 참조 를 프로젝트에 추가하면됩니다 .

솔루션 탐색기 -> 참조 -> 참조 추가 ...- > (어셈블리 : 프레임 워크) -> 아래로 스크롤하여 System.Windows.Forms 어셈블리-> 확인을 확인 합니다.

이제 System.Windows.Forms를 사용하여 추가 할 수 있습니다 . 이전과 마찬가지로 wpf 프로젝트에서 진술하고 화면을 사용하십시오.


이것이 가장 쉬운 해결책입니다. 꽤 큰 어셈블리를 추가하는 것 외에 이런 식으로하지 않는 좋은 이유가 있습니까?
AeonOfTime

3

또한 현재 화면 크기, 특히 작업 표시 줄 너비를 제외한 사각형을 반환하는 작업 영역이 필요했습니다.

마우스가있는 위치까지 오른쪽과 아래쪽으로 열리는 창을 재배치하기 위해 사용했습니다. 창이 상당히 크기 때문에 많은 경우 화면 경계를 벗어났습니다. 다음 코드는 @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;
        }
    }
}

몇 가지 설명 :

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>

1

나는 요구 사항을 이해합니다. 문제는 이러한 값을 얻기위한 WPF 메서드가 있다는 것입니다.하지만 그렇습니다. 해결책은 이러한 모든 해결 방법을 얻는 것이 아니라 깨끗한 디자인 및 개발에 따라 초기 접근 방식을 변경하는 것입니다.

A) 초기 메인 창을 화면으로 설정

B) 유용한 WPF 메서드를 포함하여 ActualWindow의 값을 가져옵니다.

C) 크기 조정, 최소화 등 원하는 동작에 대해 원하는만큼 Windows를 추가 할 수 있지만 이제는 항상로드 및 렌더링 된 화면에 액세스 할 수 있습니다.

다음 예제에주의하십시오. 그런 종류의 접근 방식을 사용해야하는 코드가 있지만 작동해야합니다 (화면의 각 모서리에 대한 포인트를 제공합니다). Working Example on Single, 듀얼 모니터 및 다양한 해상도 (Primal Main Window Class 내) :

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

1

전체 화면 창 ()을 사용하는 경우 다음 과 같이 WindowState = WindowState.Maximized, WindowStyle = WindowStyle.None내용을 래핑 할 수 있습니다 System.Windows.Controls.Canvas.

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

그럼 당신은 사용할 수 MyCanvas.ActualWidthMyCanvas.ActualHeight고려 및 장치 독립적 인 단위로 촬영 DPI 설정을 현재 화면의 해상도를 얻을 수 있습니다. 최대화 된 창 자체가하는 것처럼 여백을 추가하지 않습니다.

(Canvas는 UIElements를 자식으로 허용 하므로 모든 콘텐츠에서 사용할 수 있어야합니다.)


0

XAML의 화면 중앙에 창을 표시 WindowStartupLocation="CenterOwner"한 다음 WindowLoaded ()를 호출합니다.

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


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

4
이전 답변과 마찬가지로 이것은 기본 화면 에만 해당됩니다 . 현재 화면이 필요했습니다 .
Nils

-4

그것은 함께 작동합니다

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

2 대의 모니터에서 테스트했습니다.


10 년 5 월 18 일 15:52의 답변을 보면-당신의 것과 똑같은 것이 VirtualScreen모든 화면에 걸쳐 있음을 알 수 있습니다-따라서 두 개 이상의 화면이 있으면 작동하지 않습니다!
닐스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.