<MetroControls:MetroWindow x:Class="MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...
SaveWindowPosition="True"
...>
这里的SaveWindowPosition属性设置为True之后,就可以实现窗口前回最后停留的位置信息的保存和读取。
经过调查发现, MahApps.Metro.Controls里,实现窗口位置读存的函数是LoadWindowState和SaveWindowState。
protected virtual void LoadWindowState()
{
if (this._settings == null)
{
return;
}
this._settings.Reload();
if (!this._settings.Placement.HasValue || this._settings.Placement.Value.normalPosition.IsEmpty)
{
return;
}
try
{
WINDOWPLACEMENT value = this._settings.Placement.Value;
value.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
value.flags = 0;
value.showCmd = ((value.showCmd == 2) ? 1 : value.showCmd);
UnsafeNativeMethods.SetWindowPlacement(new WindowInteropHelper(this._window).Handle, ref value);
}
catch (Exception innerException)
{
throw new MahAppsException("Failed to set the window state from the settings file", innerException);
}
}
protected virtual void SaveWindowState()
{
if (this._settings == null)
{
return;
}
IntPtr handle = new WindowInteropHelper(this._window).Handle;
WINDOWPLACEMENT wINDOWPLACEMENT = default(WINDOWPLACEMENT);
wINDOWPLACEMENT.length = Marshal.SizeOf(wINDOWPLACEMENT);
UnsafeNativeMethods.GetWindowPlacement(handle, ref wINDOWPLACEMENT);
if (wINDOWPLACEMENT.showCmd != 0 && wINDOWPLACEMENT.length > 0)
{
RECT normalPosition;
if (wINDOWPLACEMENT.showCmd == 1 && UnsafeNativeMethods.GetWindowRect(handle, out normalPosition))
{
wINDOWPLACEMENT.normalPosition = normalPosition;
}
if (!wINDOWPLACEMENT.normalPosition.IsEmpty)
{
this._settings.Placement = new WINDOWPLACEMENT?(wINDOWPLACEMENT);
}
}
this._settings.Save();
}
进一步可以知道,窗口位置信息的获取是使用GetWindowPlacement函数,重新设回前回 位置使用的是SetWindowPlacement函数。可以知道,这两个函数是Windows的API函数。
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
即,WPF的MetroWindow风格窗口的位置自动记忆功能。使用的是GetWindowPlacement和GetWindowRect系统函数取得窗口位置信息并保存,下
次启动窗口时,取读取前回的位置信息,并用SetWindowPlacement系统函数设置回去。