Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Window ActualTop, ActualLeft

Tags:

c#

.net

wpf

What is the correct way to retrieve a window's position in WPF?

Here's some attempts I made. First attempt, the obvious

Point GetPosition(Window win)
{
    return new Point(win.Top, win.Left);
}

but this returns the "wrong" position when the window is maximized. Second attempt:

Point GetPosition(Window win)
{
    if (win.WindowState == WindowState.Maximized)
        return new Point(0, 0);
    else
        return new Point(win.Top, win.Left);
}

Almost there, but there is still an issue: when you have two (or more) screens and the window is maximized in the second screen you get a (0, 0) position that does not reflect the window's actual position.

I noticed that Window has _actualTop and _actualLeft private members, but no public property to expose them.

How do you retrieve the correct value?

like image 809
Francesco De Vittori Avatar asked Aug 30 '10 13:08

Francesco De Vittori


2 Answers

You can use reflection if you don't want to rely on Winforms or PI

private double GetWindowLeft(Window window)
    {
        if (window.WindowState == WindowState.Maximized)
        {
            var leftField = typeof(Window).GetField("_actualLeft", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            return (double)leftField.GetValue(window);
        }
        else
            return window.Left;
    }
like image 58
Tooraj Helmi Avatar answered Oct 17 '22 22:10

Tooraj Helmi


Here's a solution that builds on P/Invoke of GetWindowRect, but uses extension methods to make your code look nicer. You use myWindow.ActualTop() and myWindow.ActualLeft() in your code.

static class WindowExtensions
{
    [StructLayout(LayoutKind.Sequential)]
    struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);


    public static double ActualTop(this Window window)
    {
        switch (window.WindowState)
        {
            case WindowState.Normal:
                return window.Top;
            case WindowState.Minimized:
                return window.RestoreBounds.Top;
            case WindowState.Maximized:
                {
                    RECT rect;
                    GetWindowRect((new WindowInteropHelper(window)).Handle, out rect);
                    return rect.Top; 
                }
        }
        return 0;
    }
    public static double ActualLeft(this Window window)
    {
        switch (window.WindowState)
        {
            case WindowState.Normal:
                return window.Left;
            case WindowState.Minimized:
                return window.RestoreBounds.Left;
            case WindowState.Maximized:
                {
                    RECT rect;
                    GetWindowRect((new WindowInteropHelper(window)).Handle, out rect);
                    return rect.Left;
                }
        }
        return 0;
    }
}
like image 43
LeMaInAn Avatar answered Oct 17 '22 20:10

LeMaInAn