AvalonDock 2.0浮动窗口在MainWindow最小化/恢复时失去最大化状态

时间:2014-09-21 21:11:06

标签: c# restore handle minimize avalondock

我正在尝试在辅助监视器上实现VS样式的MainWindow +停靠内容主机。 Avalon码头可以优雅地完成工作。 直到最小化窗口,即。

恢复后,最大化的“对接主机”(LayoutAnchorablePane)会将其大小和位置重置为预先最大化的位置。

这是因为在最大化avalon dock 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来获取最小化的位置和大小,并在最大化时恢复它。

但是,我根本没有想法如何获得浮动锚的处理。

任何关于浮子手柄或其他方面的建议都将不胜感激。 谢谢你的时间。

2 个答案:

答案 0 :(得分:1)

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

一般的想法是忽略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();
    }
}

那就是它!

答案 1 :(得分:0)

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

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

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

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

在我的情况下,我已经注意到AvalonDock v.2.6中的问题,并按照上面链接的说明以及检查文件的最新版本here in the repository我解决了问题。