/// <summary> /// Looks up a window in the user settings and returns its saved position. /// </summary> /// <param name = "name">The name.</param> /// <returns> /// The saved window position if it exists. Null if the entry /// doesn't exist, or would not be visible on any screen in the user's /// current display setup. /// </returns> private static WindowPosition LookupWindowPosition(string name) { try { if (_windowPositionList == null) { _windowPositionList = WindowPositionList.Load(); } var position = _windowPositionList?.Get(name); if (position == null || position.Rect.IsEmpty) { return(null); } if (Screen.AllScreens.Any(screen => screen.WorkingArea.IntersectsWith(position.Rect))) { return(position); } } catch (Exception) { // TODO: howto restore a corrupted config? } return(null); }
/// <summary> /// Save the position of a form to the user settings. Hides the window /// as a side-effect. /// </summary> /// <param name = "name">The name to use when writing the position to the /// settings</param> private void SavePosition(string name) { if (!_needsPositionSave) { return; } _needsPositionSave = false; try { var rectangle = WindowState == FormWindowState.Normal ? DesktopBounds : RestoreBounds; var formWindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Maximized : FormWindowState.Normal; if (_windowPositionList == null) { _windowPositionList = WindowPositionList.Load(); if (_windowPositionList == null) { return; } } WindowPosition windowPosition = _windowPositionList.Get(name); // Don't save location when we center modal form if (windowPosition != null && Owner != null && _windowCentred) { if (rectangle.Width <= windowPosition.Rect.Width && rectangle.Height <= windowPosition.Rect.Height) { rectangle.Location = windowPosition.Rect.Location; } } var position = new WindowPosition(rectangle, DpiUtil.DpiX, formWindowState, name); _windowPositionList.AddOrUpdate(position); _windowPositionList.Save(); } catch { // TODO: how to restore a corrupted config? } }
/// <summary> /// Save the position of a form to the user settings. Hides the window /// as a side-effect. /// </summary> /// <param name="form">The form to save the position for.</param> public void SavePosition(Form form) { try { var rectangle = form.WindowState == FormWindowState.Normal ? form.DesktopBounds : form.RestoreBounds; var formWindowState = form.WindowState == FormWindowState.Maximized ? FormWindowState.Maximized : FormWindowState.Normal; if (_windowPositionList is null) { _windowPositionList = WindowPositionList.Load(); if (_windowPositionList is null) { return; } } var name = form.GetType().Name; WindowPosition windowPosition = _windowPositionList.Get(name); var windowCentred = form.StartPosition == FormStartPosition.CenterParent; // Don't save location when we center modal form if (windowPosition is not null && form.Owner is not null && windowCentred) { if (rectangle.Width <= windowPosition.Rect.Width && rectangle.Height <= windowPosition.Rect.Height) { rectangle.Location = windowPosition.Rect.Location; } } var position = new WindowPosition(rectangle, DpiUtil.DpiX, formWindowState, name); _windowPositionList.AddOrUpdate(position); _windowPositionList.Save(); } catch { // TODO: how to restore a corrupted config? } }
/// <summary> /// Retrieves a persisted position for the given <paramref name="form"/>. /// </summary> /// <param name="form">The form to look the position for.</param> /// <returns>The form's persisted position; otherwise <see langword="null"/>.</returns> public WindowPosition?LoadPosition(Form form) { try { _windowPositionList ??= WindowPositionList.Load(); var pos = _windowPositionList?.Get(form.GetType().Name); if (pos is not null && !pos.Rect.IsEmpty) { return(pos); } } catch { // TODO: how to restore a corrupted config? } return(null); }
/// <summary> /// Save the position of a form to the user settings. Hides the window /// as a side-effect. /// </summary> /// <param name = "name">The name to use when writing the position to the /// settings</param> private void SavePosition(String name) { try { var rectangle = WindowState == FormWindowState.Normal ? DesktopBounds : RestoreBounds; var formWindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Maximized : FormWindowState.Normal; // Write to the user settings: if (_windowPositionList == null) { _windowPositionList = WindowPositionList.Load(); } WindowPosition windowPosition = _windowPositionList.Get(name); // Don't save location when we center modal form if (windowPosition != null && Owner != null && _windowCentred) { if (rectangle.Width <= windowPosition.Rect.Width && rectangle.Height <= windowPosition.Rect.Height) { rectangle.Location = windowPosition.Rect.Location; } } int deviceDpi = GetCurrentDeviceDpi(); var position = new WindowPosition(rectangle, deviceDpi, formWindowState, name); _windowPositionList.AddOrUpdate(position); _windowPositionList.Save(); } catch (Exception) { // TODO: howto restore a corrupted config? } }
/// <summary> /// Restores the position of a form from the user settings. Does /// nothing if there is no entry for the form in the settings, or the /// setting would be invisible on the current display configuration. /// </summary> protected virtual void RestorePosition() { if (!_needsPositionRestore) { return; } if (WindowState == FormWindowState.Minimized) { return; } _windowCentred = StartPosition == FormStartPosition.CenterParent; var position = LookupWindowPosition(GetType().Name); if (position == null) { return; } _needsPositionRestore = false; if (!Screen.AllScreens.Any(screen => screen.WorkingArea.IntersectsWith(position.Rect))) { if (position.State == FormWindowState.Maximized) { WindowState = FormWindowState.Maximized; } return; } SuspendLayout(); StartPosition = FormStartPosition.Manual; if (FormBorderStyle == FormBorderStyle.Sizable || FormBorderStyle == FormBorderStyle.SizableToolWindow) { Size = DpiUtil.Scale(position.Rect.Size, originalDpi: position.DeviceDpi); } if (Owner == null || !_windowCentred) { var location = DpiUtil.Scale(position.Rect.Location, originalDpi: position.DeviceDpi); if (FindWindowScreen(location) is Rectangle rect) { location.Y = rect.Y; } DesktopLocation = location; } else { // Calculate location for modal form with parent Location = new Point( Owner.Left + (Owner.Width / 2) - (Width / 2), Math.Max(0, Owner.Top + (Owner.Height / 2) - (Height / 2))); } if (WindowState != position.State) { WindowState = position.State; } ResumeLayout(); return; Rectangle?FindWindowScreen(Point location) { var distance = new SortedDictionary <float, Rectangle>(); foreach (var rect in Screen.AllScreens.Select(screen => screen.WorkingArea)) { if (rect.Contains(location) && !distance.ContainsKey(0.0f)) { return(null); // title in screen } int midPointX = rect.X + (rect.Width / 2); int midPointY = rect.Y + (rect.Height / 2); var d = (float)Math.Sqrt(((location.X - midPointX) * (location.X - midPointX)) + ((location.Y - midPointY) * (location.Y - midPointY))); distance.Add(d, rect); } return(distance.FirstOrDefault().Value); } WindowPosition LookupWindowPosition(string name) { try { if (_windowPositionList == null) { _windowPositionList = WindowPositionList.Load(); } var pos = _windowPositionList?.Get(name); if (pos != null && !pos.Rect.IsEmpty) { return(pos); } } catch { // TODO: how to restore a corrupted config? } return(null); } }