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
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
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().
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;
}
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;
}
}