tags:

views:

806

answers:

3

I know I can get the size of the primary screen by using

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

But how do I get the size of the current screen ?
(Multi-Screen users do not always use the primary screen and not all screens are using the same resolution, right ?)
Nice would be a way to acces the size from xaml, but doing so from code (c#) would suffice.

+2  A: 

As far as I know there is no native WPF function to get dimensions of the current monitor. Instead you could PInvoke native multiple display monitors functions, wrap them in managed class and expose all properties you need to consume them from XAML.

Anvaka
That is exactly what I feared -- the need to P/Invoke the stuff or accessing System.Windows.Forms.Screen somehow. And when doing so I always need to calculte the "device independent pixels"... Thanks, though.
Nils
Yes... Maybe SystemParameters.ConvertPixel() function will also help you. It's internal, but Reflector doesn't care :)...
Anvaka
+1  A: 

I created a little wrapper around the Screen from System.Windows.Forms, currently everything works... Not sure about the "device independent pixels", though.

    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, hieght 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;
        }            
    }
Nils
Thanks for this great little wrapper, note that the global::Rect needed converting to just plain Rect when I used with WPF 3.5.
Andy Dent
+1  A: 

Take the time to scan through the SystemParameters members.

VirtualScreenWidth VirtualScreenHeight

These even take into account the relative positions of the screens.

Only tested with two monitors

dana
dana - I have not tested this, but doesn't VirtualScreen* return the full size of all screens? - I specifically Need the size of one screen (the one in which the current window resides).
Nils
VirtualScreen seems to refer to the size of all screens
Thomas