web-dev-qa-db-ja.com

WPFで現在の画面のサイズを取得する方法は?

私は私が使用して主画面のサイズを取得できることを知っています

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

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

XAMLからサイズにアクセスできればいいのですが、コード(C#)からアクセスできれば十分です。

77
Nils

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

12
Anvaka

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

ここでバディ。これにより、ワークエリアの幅と高さのみが得られます

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

これにより、ウィンドウの左上に基づいて現在の画面が表示され、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));
         }
     }
}
6
E.J.

SystemParametersメンバーをスキャンするのに時間がかかります。

  • VirtualScreenWidth
  • VirtualScreenHeight

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

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

5
dana

System.Windows.Formsクラスの使用に慣れている場合は、プロジェクトにSystem.Windows.Formsクラスの参照を追加だけを実行できます。

ソリューションエクスプローラー-> 参照-> 参照の追加...-> (アセンブリ:フレームワーク)-> scrollダウンして確認してくださいSystem.Windows.Forms Assembly-> [〜#〜] ok [〜#〜].

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

3

私は要求を理解しています。問題は、これらの値を取得するためのWPFメソッドがあります-しかし、はい、貢献者の1人は直接ではなく、正しいです。ソリューションは、これらすべての回避策を取得するのではなく、クリーンな設計と開発に応じて初期アプローチを変更することです。

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

B)多数の便利なWPFメソッドを含むActualWindowの値を取得する

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

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

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
Dororo

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

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

XAMLで画面の中央にウィンドウを配置_WindowStartupLocation="CenterOwner"_その後、WindowLoaded()を呼び出します

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

0
mikesl