简体   繁体   English

在 Aero Snap 后将 WinForms 窗口恢复到正确位置

[英]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.当我将 WinForms 窗口拖到屏幕顶部以执行最大化“Aero Snap”时,如果我在此之后点击“恢复”按钮,窗口将恢复到正确的大小,但在错误的位置。 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.显然,WinForms 窗口恢复到它最大化之前的最后一个拖动位置,该位置位于屏幕顶部为了执行 Aero Snap 而被拖动的位置。

This behavior is incorrect and annoying.这种行为是不正确和烦人的。 You can see the correct behavior by following those same steps for a Windows Explorer window.您可以通过对 Windows 资源管理器窗口执行相同的步骤来查看正确的行为。 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).在 Aero Snap 之后,Windows 资源管理器窗口会正确还原到上次放置的还原位置(无论它在被拖动以执行 Aero Snap 之前所处的位置)。

How can I make a WinForms window restore to the correct location after an Aero Snap, like a Windows Explorer window does?在 Aero Snap 之后,如何让 WinForms 窗口恢复到正确的位置,就像 Windows 资源管理器窗口一样?

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.我可以尝试挂钩表单定位事件并保存最后删除的还原位置,并在 Aero Snap 后的还原后还原该位置,但我希望有一种更简单的方法。

You can override the OnResizeBegin , OnResizeEnd and OnSizeChanged methods to:您可以将OnResizeBeginOnResizeEndOnSizeChanged方法覆盖为:

  1. store a Form's current Location when it's first dragged (when you begin to drag a Form around the OnResizeBegin is called)在第一次拖动时存储表单的当前位置(当您开始在OnResizeBegin周围拖动表单时)
  2. clear the stored values if the Form is released ( OnResizeEnd is called) while it's WindowState is FormWindowState.Normal如果 Form 被释放( OnResizeEnd被调用),而它的WindowStateFormWindowState.Normal ,则清除存储的值
  3. finally restore the Form.Location when OnSizeChanged notifies that the Form.WindowState changes from FormWindowState.Maximized to FormWindowState.Normal .OnSizeChanged通知Form.WindowStateFormWindowState.Maximized更改为Form.Location时,最终恢复FormWindowState.Normal

If you use a Controller or similar, you can subscribe to the corresponding events instead.如果您使用 Controller 或类似的,您可以改为订阅相应的事件。


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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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