WPFで現在の画面のサイズを取得するにはどうすればよいですか?


87

を使用してプライマリ画面のサイズを取得できることを知っています

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

しかし、現在の画面のサイズを取得するにはどうすればよいですか?(マルチスクリーンユーザーは常にプライマリ画面を使用するとは限らず、すべての画面が同じ解像度を使用しているわけではありませんよね?)

XAMLからサイズにアクセスできると便利ですが、コード(C#)からアクセスするだけで十分です。


1
「現在」を定義します。ウィンドウは、一度に複数の画面に表示できます。
ジムバルター2018

回答:


13

私の知る限り、現在のモニターのサイズを取得するためのネイティブWPF関数はありません。代わりに、ネイティブのマルチディスプレイモニター関数をPInvokeし、それらをマネージクラスでラップして、XAMLからそれらを使用するために必要なすべてのプロパティを公開することができます。


それはまさに私が恐れていたものです-何かをP / Invokeするか、何らかの方法でSystem.Windows.Forms.Screenにアクセスする必要があります。そしてそうするとき、私は常に「デバイスに依存しないピクセル」を計算する必要があります...しかし、ありがとう。
ニルス

はい...多分SystemParameters.ConvertPixel()関数もあなたを助けるでしょう。それは内部ですが、Reflectorは気にしません:)...
Anvaka 2009

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

このすばらしい小さなラッパーに感謝します。WPF3.5で使用した場合、global :: Rectを単純なRectに変換する必要があることに注意してください。
アンディデント2010年

1
私はこれが好き。確かに少し作業が必要ですが、100%の解決策を見つけることは期待していません。
jeff 2015年

4
よく働く。GetRectメソッドを拡張して、デバイスに依存しないピクセルでRectを返しました。privateRectGetRect(Rectangle value){var pixelWidthFactor = SystemParameters.WorkArea.Width / this.screen.WorkingArea.Width; var pixelHeightFactor = SystemParameters.WorkArea.Height / this.screen.WorkingArea.Height; 新しいRectを返す{X = value.X * pixelWidthFactor、Y = value.Y * pixelHeightFactor、Width = value.Width * pixelWidthFactor、Height = value.Height * pixelHeightFactor}; }
ユルゲンバイエル

1
@JürgenBayerからコードを追加すると、回答がさらに改善されると思います。デバイスに依存しないピクセルに問題があり、Jürgenのコードで解決しました。あなたがた両方に感謝します。
ブルーノV

3
@Jürgen:あなたの方法は非常に特殊な状況でのみ機能すると思います。「this.screen」のアスペクト比がプライマリモニター(現在のモニターではなく、メソッドが常に参照として使用する)と異なる場合、幅と高さのスケールファクターが誤って取得され、画面のサイズが正しくなくなります。現在の画面のDPI設定がプライマリ画面と異なる場合、境界はすべて間違っています。私のシステムでは、返されるRectのすべての値が(乱暴に)正しくありません。
ウィルフォード2017年

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は、他の回答の1つにコメントを投稿することを意図していました。これは、これとはまったく関係がないためです。
ジムバルター2018

@ jim-balter投票済み-実際、これがここでの最良の答えです。作業領域を取得し、ダイアログが境界を超えていないことを確認するために画面が必要でした。ここに解決策を投稿します。ポイントの答えをすばやく得るためのEJへの称賛。
ユベントス

^奇妙なコメント。
ジムバルター

5

時間をかけてSystemParametersメンバーをスキャンしてください。

  • VirtualScreenWidth
  • VirtualScreenHeight

これらは、画面の相対的な位置も考慮に入れています。

2台のモニターでのみテストされています。


9
dana-これはテストしていませんが、VirtualScreen *はすべての画面のフルサイズを返しませんか?-特に1つの画面(現在のウィンドウが存在する画面)のサイズが必要です。
ニルス2010年

1
VirtualScreenは、すべての画面のサイズを参照しているようです
Thomas

1
1つの鉱山では、4つの画面すべてを合わせたサイズが返されました。
DJ van Wyk 2017

3

なぜこれを使わないのですか?

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

画面はWPFではなくWindows.Formsですが、これが出発点です。当時使用していたソリューション(stackoverflow.com/a/2118993/180156)を見ると、これはまさに私が行ったことですがSystem.Windows.Forms.Screen、デバイスに依存しないピクセルに対処するためにラップしました
Nils

3

System.Windows.Formsクラスの使用に精通している場合は、System.Windows.Formsクラスの参照をプロジェクトに追加するだけです。

ソリューションエクスプローラー->参照->参照の追加...- > (アセンブリ:フレームワーク) ->下にスクロールして、System.Windows.Formsアセンブリ-> OKを確認します。

これで、System.Windows.Forms使用して追加できます。以前と同じように、wpfプロジェクトで画面をステートメントして使用します。


これは断然最も簡単な解決策です。かなり大きなアセンブリを追加する以外に、このようにしない理由はありますか?
aeonOfTime 2018

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メソッドがありますが、そうです、貢献者の1人は正しく、直接ではありません。解決策は、これらすべての回避策を取得することではなく、クリーンな設計と開発に従って初期アプローチを変更することです。

A)最初のメインウィンドウを画面に設定します

B)大量の便利なWPFメソッドを含むActualWindowの値を取得します

C)サイズ変更や最小化など、必要な動作に合わせてWindowsをいくつでも追加できますが、ロードおよびレンダリングされた画面にはいつでもアクセスできます。

次の例に注意してください。そのようなアプローチを使用する必要があるコードがいくつかありますが、それは機能するはずです(画面の各コーナーにポイントが与えられます):シングルでの作業例、デュアルモニターと異なる解像度(プライマルメインウィンドウクラス内):

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.ActualWidthし、MyCanvas.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
前の回答と同様に、これはプライマリ画面専用です。現在の画面が必要でした。
ニルス

-4

それはで動作します

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

2台のモニターでテスト済み。


2010年5月18日15:52の回答を見ると、これはVirtualScreenすべての画面にまたがっていることがわかります。したがって、複数の画面がある場合、これは機能しません。
ニルス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.