Window ActualTop, ActualLeft

前端 未结 4 1190
小蘑菇
小蘑菇 2020-12-02 02:11

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 wi         


        
相关标签:
4条回答
  • 2020-12-02 02:38

    When the window is moved by the user, the Top and Left properties are not updated according to the change of location. But it is possible to use RestoreBounds.Top and RestoreBounds.Left as "ActualTop" and "ActualLeft". Ofcauce the maximized and minimized case is special, and must be treated separately

    0 讨论(0)
  • 2020-12-02 02:50

    Yes, awkward. You've got bigger problems, (0, 0) won't be valid even on the primary monitor if the user put the taskbar on the left or the top. Like I did. You can get help from the Windows Forms Screen class. Use its FromPoint() method, then the WorkingArea property. Or the Bounds property if you allow the window to go full-screen.

    Personally, I'd just P/Invoke GetWindowRect().

    0 讨论(0)
  • 2020-12-02 02:51

    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;
        }
    
    0 讨论(0)
  • 2020-12-02 02:54

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题