【问题标题】:AvalonDock 2.0 Floating Window looses maximized state on MainWindow minimize / restoreAvalonDock 2.0 浮动窗口在 MainWindow 最小化/恢复上失去最大化状态
【发布时间】:2014-09-21 21:11:06
【问题描述】:

我正在尝试在辅助监视器上实现 VS 风格的 MainWindow + 对接内容主机。 Avalon 坞站优雅地完成了这项工作。 直到最小化窗口为止。

还原后,最大化的“停靠主机”(LayoutAnchorablePane) 会将其大小和位置重置为最大化前的大小和位置。

这是因为在最大化 avalon 码头 LayoutAnchorablePane 时,不会触发 Property Changed 事件。此外,浮动宽度属性不会更新。

这就是我第一次尝试的原因__

    public Window3()
    {
        InitializeComponent();

        // Intercept the minimize event and cancel it.
        this.SourceInitialized += OnSourceInitialized; 

    }

    private void OnSourceInitialized(object sender, EventArgs e)
    {
        var source = (HwndSource)PresentationSource.FromVisual(this);
        if (source != null) source.AddHook(HandleMessages);
    }

    //These store the location and size of Left - the Layout Anchorable to be placed on a sec monitor
    private Point _location;
    private Size _size;

    private IntPtr HandleMessages(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg != 0x0112 || ((int) wParam & 0xFFF0) != 0xF020) return IntPtr.Zero;
        //This means a minimize for the Main Window. Cancel it.
        handled = true;
        //Get the sec monitor anchorable size and location
        _location = new Point(Left.FloatingLeft, Left.FloatingTop);
        _size = new Size(Left.FloatingWidth, Left.FloatingHeight);

        //finally minimize the window
        WindowState = WindowState.Minimized;


        return IntPtr.Zero;
    } 

    private void Window3_OnStateChanged(object sender, EventArgs e)
    {
        //Restore the width and location for the sec monitor anchorable
        // Fail. Cry. Cry a lot...
        if (WindowState == WindowState.Maximized)
        {
            Left.FloatingLeft = _location.X;
            Left.FloatingTop = _location.Y;
            Left.FloatingWidth = _size.Width;
            Left.FloatingHeight = _size.Height;
        }
    }

__ 不起作用。

这些最大化/恢复事件是无法访问的。它们存储在 Controls/Shell/SystemCommands.cs 中

    public static void MaximizeWindow(Window window)
    {
        Verify.IsNotNull(window, "window");
        _PostSystemCommand(window, SC.MAXIMIZE);
    }

    private static void _PostSystemCommand(Window window, SC command)
    {
        IntPtr hwnd = new WindowInteropHelper(window).Handle;
        if (hwnd == IntPtr.Zero || !NativeMethods.IsWindow(hwnd))
        {
            return;
        }

        NativeMethods.PostMessage(hwnd, WM.SYSCOMMAND, new IntPtr((int)command), IntPtr.Zero);
    }

我已阅读有关 avalondock 的 codeplex 讨论的一些提示,但我认为它们适用于以前的版本并且不再有效。

我正在考虑使用 user32 GetWindowRect 和 SetWindowPos 在最小化时获取位置和大小,并在最大化时恢复它。

但是,我根本不知道如何获得浮动锚点的手柄。

任何关于浮动手柄或其他方面的建议,将不胜感激。 感谢您的宝贵时间。

【问题讨论】:

  • 您找到解决方案了吗?我遇到了这个问题并正在寻找解决方法。我注意到当我使用WindowState==Maximized 最大化时调用LayoutFloatingWindowControl.OnStateChanged(EventArgs),并再次使用WindowState==Normal 从最小化还原时调用,但不知道从那里去哪里。
  • 抱歉,我没有找到可行的解决方案。

标签: c# restore handle minimize avalondock


【解决方案1】:

我也遇到了同样的问题(在 WPF 工具包示例中也可见)并找到了解决方案!

总体思路是忽略 Windows 发送的WindowState 更改并始终恢复内部状态:

protected override void OnStateChanged(EventArgs e)
{
    // Windows sometimes send unwanted state changes (when minimizing application for instance)
    // We force internal state to be used
    WindowState = IsMaximized ? WindowState.Maximized : WindowState.Normal;
    base.OnStateChanged(e);
}

WM_SYSCOMMAND 处理不当(0xFFF0 掩码丢失):

case Win32Helper.WM_SYSCOMMAND:
    int command = (int)wParam & 0xFFF0;
    if (command == Win32Helper.SC_MAXIMIZE || command == Win32Helper.SC_RESTORE)
    {
        UpdateMaximizedState(command == Win32Helper.SC_MAXIMIZE);
    }

我还更新了UpdateMaximizedState 以更改内部状态:

void UpdateMaximizedState( bool isMaximized )
{
    foreach( var posElement in Model.Descendents().OfType<ILayoutElementForFloatingWindow>() )
    {
        posElement.IsMaximized = isMaximized;
    }
    IsMaximized = isMaximized;
    WindowState = isMaximized ? WindowState.Maximized : WindowState.Normal;
}

附带说明一下,IsMaximized 现在是一个 get/set 属性:

public bool IsMaximized
{
    get { return (bool)GetValue(IsMaximizedProperty); }
    set
    {
        SetValue(IsMaximizedProperty, value);
        UpdatePositionAndSizeOfPanes();
    }
}

就是这样!

【讨论】:

    【解决方案2】:

    Julien Richard 是对的,对于那些面临同样问题但不知道在 AvalonDock 源代码中何处修复它的人,我想指出这里报告的详细解决方案:

    http://wpftoolkit.codeplex.com/workitem/22296

    在不同的情况下,LauoutFloatingWindowControl 的最大化状态将在 AvalonDock 中失败,具体取决于其版本,例如:

    • 当 AvalonDock 布局被反序列化时
    • 从任务栏恢复主窗口时
    • 拖动最大化的浮动窗口时

    就我而言,我注意到 AvalonDock v.2.6 中的问题,并按照上面链接的说明以及检查文件here in the repository 的最新版本,我解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      • 2017-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多