简体   繁体   中英

Restore WinForms window to correct position after Aero Snap

When I drag a WinForms window to the top of the screen to perform a Maximize "Aero Snap", if I then hit the "Restore" button after this, the window is restored to the correct size but at the wrong location. It flickers to the correct location for a moment, but then it immediately moves to the top of the screen with its title bar halfway off the screen.

Apparently, the WinForms window restores to its last dragged location before it was maximized, which was at the top of the screen where it was dragged in order to do the Aero Snap.

This behavior is incorrect and annoying. You can see the correct behavior by following those same steps for a Windows Explorer window. After an Aero Snap, the Windows Explorer window correctly restores to the last dropped restore location (wherever it was sitting before it was dragged to do the Aero Snap).

How can I make a WinForms window restore to the correct location after an Aero Snap, like a Windows Explorer window does?

I could try and hook into the form positioning events and save the last-dropped restore location, and restore that after a Restore after an Aero Snap, but I'm hoping there's a simpler way.

You can override the OnResizeBegin , OnResizeEnd and OnSizeChanged methods to:

  1. store a Form's current Location when it's first dragged (when you begin to drag a Form around the OnResizeBegin is called)
  2. clear the stored values if the Form is released ( OnResizeEnd is called) while it's WindowState is FormWindowState.Normal
  3. finally restore the Form.Location when OnSizeChanged notifies that the Form.WindowState changes from FormWindowState.Maximized to FormWindowState.Normal .

If you use a Controller or similar, you can subscribe to the corresponding events instead.


Point beginDragLocation = Point.Empty;
FormWindowState beginDragFormState = FormWindowState.Normal;

protected override void OnResizeBegin(EventArgs e) 
{
    base.OnResizeBegin(e);
    beginDragLocation = this.Location;
}

protected override void OnResizeEnd(EventArgs e)
{
    base.OnResizeEnd(e);
    if (this.WindowState != FormWindowState.Maximized) {
        beginDragLocation = Point.Empty;
    }
}

protected override void OnSizeChanged(EventArgs e)
{
    base.OnSizeChanged(e);
    if (beginDragFormState == FormWindowState.Maximized && beginDragLocation != Point.Empty) {
        BeginInvoke(new Action(() => this.Location = beginDragLocation));
    }
    beginDragFormState = this.WindowState;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM