【问题标题】:Restore WinForms window to correct position after Aero SnapAero Snap 后将 WinForms 窗口恢复到正确位置
【发布时间】:2020-03-03 17:34:03
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: windows winforms window aero-snap


    【解决方案1】:

    您可以覆盖OnResizeBeginOnResizeEndOnSizeChanged 方法:

    1. 在第一次拖动表单时存储表单的当前位置(当您开始围绕 OnResizeBegin 调用表单时)
    2. 如果表单被释放(OnResizeEnd 被调用)而它的WindowStateFormWindowState.Normal,则清除存储的值
    3. OnSizeChanged通知Form.WindowStateFormWindowState.Maximized变为FormWindowState.Normal时,最终恢复Form.Location

    如果你使用控制器或类似的,你可以订阅相应的事件。


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

    【讨论】:

      猜你喜欢
      • 2012-01-12
      • 2012-03-29
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      相关资源
      最近更新 更多