0

当我将 WinForms 窗口拖到屏幕顶部以执行最大化“Aero Snap”时,如果在此之后点击“恢复”按钮,窗口将恢复到正确的大小但位置错误。它在正确的位置闪烁片刻,但随后立即移动到屏幕顶部,其标题栏位于屏幕的一半。

显然,WinForms 窗口会恢复到其最大化之前的最后一个拖动位置,该位置位于屏幕顶部,以便执行 Aero Snap。

这种行为是不正确且令人讨厌的。通过对 Windows 资源管理器窗口执行相同的步骤,您可以看到正确的行为。在 Aero Snap 之后,Windows 资源管理器窗口会正确还原到最后放置的还原位置(无论它在被拖动以执行 Aero Snap 之前所在的位置)。

在 Aero Snap 之后,如何使 WinForms 窗口恢复到正确的位置,就像 Windows 资源管理器窗口一样?

我可以尝试挂钩表单定位事件并保存最后删除的恢复位置,并在 Aero Snap 后恢复后恢复该位置,但我希望有一种更简单的方法。

4

1 回答 1

0

您可以覆盖OnResizeBeginOnResizeEndOnSizeChanged方法:

  1. 首次拖动表单时存储表单的当前位置(当您开始在OnResizeBegin被调用的表单周围拖动表单时)
  2. OnResizeEnd如果 Form 被释放(被调用),则清除存储的WindowStateFormWindowState.Normal
  3. 最后恢复Form.LocationwhenOnSizeChanged通知的Form.WindowState变化从FormWindowState.MaximizedFormWindowState.Normal

如果你使用 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;
}
于 2020-03-03T22:46:34.127 回答