Avalondock 技巧之如何隐藏浮动面板停靠器

Avalondock 技巧之如何隐藏浮动面板停靠器avalondock技巧之如何隐藏浮动面板停靠器之前开发的一个项目需要实现窗口的浮出,拖拽,停靠等功能,于是想到了神器Avalondock,这个框架功能相当强大,而且能实现多种主题样式的控件,特别是窗口的浮动停靠等功能。目前该框架有收费版本和开源版本,我之前的项目使用的是avalondockv2.0的,目前最新的是v4.0。官方链接:https://archive.codeplex.com/?p=avalondock.Git链接:https://github.com/xceedsoftware

大家好,又见面了,我是你们的朋友全栈君。

avalondock 技巧之如何隐藏浮动面板停靠器

之前开发的一个项目需要实现窗口的浮出,拖拽,停靠等功能,于是想到了神器Avalondock,这个框架功能相当强大,而且能实现多种主题样式的控件,特别是窗口的浮动停靠等功能。目前该框架有收费版本和开源版本,我之前的项目使用的是avalondock v2.0的,目前最新的是v4.0。

官方链接: https://archive.codeplex.com/?p=avalondock.
Git链接: https://github.com/xceedsoftware/wpftoolkit.

在使用过程中需要用到窗口的浮出,停靠功能,每当拖拽窗口时会显示类似Visual Studio的窗口停靠器,这个功能默认就可以使用,但实际使用中却并不是处处都需要这个功能,有的时候因为用户的随意拖动会导致原始窗口发生较大变化,而且这个窗口停靠器官方并没有给出隐藏显示设置入口。
在这里插入图片描述
经过一翻stackoverflow查询,发现外国人也有这个困扰,回复里也给出了一些方式,比如说每次保存当前窗口,当发生停靠后可以一键恢复原来的窗口等,都是从接口入手解决的。我将git上的源码拉下来研究了一番,发现只要控制拖拽事件就能阻止触发这个停靠管理器的显示,于是找到了DragService.cs文件,里面实现了对拖拽功能的实现,在窗口布局控制文件LayoutFloatingWindowControl.cs找到了对鼠标右键的按下事件:

protected virtual IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        { 
   
            handled = false;

            switch (msg)
            { 
   
                case Win32Helper.NCCALCSIZE:
                    if (wParam != IntPtr.Zero)
                    { 
   
                        handled = true;
                        var client = (RECT)Marshal.PtrToStructure(lParam, typeof(RECT));
                        client.Bottom -= 1;
                        Marshal.StructureToPtr(client, lParam, false);
                    }
                    break;

                //case Win32Helper.WM_NCHITTEST:
                // { 
   
                // handled = true;
                // //var htLocation = DefWindowProc( hwnd, msg, wParam, lParam ).ToInt32();
                // //switch( htLocation )
                // //{ 
   
                // // case (int)HitTestResult.HTBOTTOM:
                // // case (int)HitTestResult.HTBOTTOMLEFT:
                // // case (int)HitTestResult.HTBOTTOMRIGHT:
                // // case (int)HitTestResult.HTLEFT:
                // // case (int)HitTestResult.HTRIGHT:
                // // case (int)HitTestResult.HTTOP:
                // // case (int)HitTestResult.HTTOPLEFT:
                // // case (int)HitTestResult.HTTOPRIGHT:
                // // htLocation = (int)HitTestResult.HTBORDER;
                // }
                // break;

                case Win32Helper.WM_ACTIVATE:
                    if (((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE)
                    { 
   
                        if (lParam == this.GetParentWindowHandle())
                        { 
   
                            Win32Helper.SetActiveWindow(_hwndSrc.Handle);
                            handled = true;
                        }
                    }
                    break;
                case Win32Helper.WM_EXITSIZEMOVE:
                    UpdatePositionAndSizeOfPanes();

                    if (_dragService != null)
                    { 
   
                        bool dropFlag;
                        var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition());
                        _dragService.Drop(mousePosition, out dropFlag);
                        _dragService = null;
                        SetIsDragging(false);

                        if (dropFlag)
                            InternalClose();
                    }

                    break;
                case Win32Helper.WM_MOVING:
                    { 
   
                        UpdateDragPosition();
                        if (this.IsMaximized)
                        { 
   
                            this.UpdateMaximizedState(false);
                        }
                    }
                    break;
                case Win32Helper.WM_LBUTTONUP: //set as handled right button click on title area (after showing context menu)
                    if (_dragService != null && Mouse.LeftButton == MouseButtonState.Released)
                    { 
   
                        _dragService.Abort();
                        _dragService = null;
                        SetIsDragging(false);
                    }
                    break;
                case Win32Helper.WM_SYSCOMMAND:
                    int command = (int)wParam & 0xFFF0;
                    if (command == Win32Helper.SC_MAXIMIZE || command == Win32Helper.SC_RESTORE)
                    { 
   
                        UpdateMaximizedState(command == Win32Helper.SC_MAXIMIZE);
                    }
                    break;
            }



            return IntPtr.Zero;
        }

其中:UpdateDragPosition() 就是实现对移动过程中触发窗口停靠器

case Win32Helper.WM_MOVING:
                    { 
   
                        UpdateDragPosition();
                        if (this.IsMaximized)
                        { 
   
                            this.UpdateMaximizedState(false);
                        }
                    }
                    break;
private void UpdateDragPosition()
        { 
   
            if (_dragService == null)
            { 
   
                
                _dragService = new DragService( this );
                SetIsDragging(true);
            }

            var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition());
            
            _dragService.UpdateMouseLocation(mousePosition);

        }

改造一下,不实现DragService即可。

private void UpdateDragPosition()
        { 
   
            if (_dragService == null)
            { 
   
                //不初始化拖拽事件
                //_dragService = new DragService( this );
                SetIsDragging(true);
            }

            var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition());
            if (_dragService != null)
            { 
   
                _dragService.UpdateMouseLocation(mousePosition);
            }

        }

重新生成一下,运行自己的程序,再也没有窗口停靠器的出现了。这下界面就不会被用户搞乱了,但想要实现的浮动停靠功能就没有了,于是自己手动通过按钮来触发浮出,停靠功能,而拖拽窗口并不会触发停靠事件。

private void btnFloatVideo_Click(object sender, RoutedEventArgs e)
        { 
   
            if (anchorable.IsFloating)
            { 
   
                this.btnFloatVideo.Content = "浮出窗口";
                anchorable.Dock();
                teleCenter.DockWidth = new GridLength(720);
                telerecord.DockWidth = new GridLength(700);
            }
            else
            { 
   
                this.btnFloatVideo.Content = "停靠窗口";
                anchorable.Float();
            }
        }

这下窗口的所有控制都在你的可控之下了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/162150.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何下载ts文件

    如何下载ts文件首先,什么是ts,请自行百度,网上资料很多,了解下基本概念就行,这里就不多做介绍了。网页中是如何播放ts文件的:网页中一般是在一个文件中描述排列顺序,这个文件一般都以m3u8为后缀,然后通过分片段不

    2022年7月1日
    23
  • nactive15激活码_最新在线免费激活2022.02.11「建议收藏」

    (nactive15激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html4KDDGND3CI-eyJsaWN…

    2022年4月1日
    132
  • 阿里云短信服务Java实现

    阿里云短信服务Java实现文章目录 1 阿里云用户权限 2 开通阿里云短信服务 3 帮助文档 4 编写测试代码真实项目应用 1 阿里云用户权限阿里云平台有很多业务 用户登录阿里云之后 要想使用业务 必须开通该业务的权限登录阿里云网站 点击右上角头像查看个人信息 点击 accesskey 选择开始使用子账户添加用户组 类似于 Linux 中的用户组和用户新创建用户组默认没有权限 点击添加权限 可以看到阿里所有权限搜索短信 sms 添加在用户组中添加用户 勾选允许编程访问创建成功后 会生成新用户组用户 accesskey

    2025年8月4日
    3
  • acwing-1080. 骑士(基环树dp)[通俗易懂]

    acwing-1080. 骑士(基环树dp)[通俗易懂]Z 国的骑士团是一个很有势力的组织,帮会中聚集了来自各地的精英。他们劫富济贫,惩恶扬善,受到了社会各界的赞扬。可是,最近发生了一件很可怕的事情:邪恶的 Y 国发起了一场针对 Z 国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的 Z 国又怎能抵挡得住 Y 国的军队。于是人们把所有希望都寄托在了骑士团身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。骑士团是肯定具备打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士有且仅有一个他自己最厌恶的骑士(当然不是他自己),他是绝对不

    2022年8月9日
    3
  • mfc可视化界面_mfc界面开发

    mfc可视化界面_mfc界面开发亲爱的BCGSoft用户,我们非常高兴地宣布BCGControlBarProfessionalforMFC和BCGSuiteforMFCv32.2正式发布!新版本改进的功能区和框架标题命令搜索、带有可选复选框的网格日期选择器、带有标签的功能区滑块等,需要最新版的可以点击这里【BCG下载】BCGControlBarProforMFCv32.2正式版下载RibbonBar1.新的全局变量globalData.m_sizeRibbonCategoryPadding和glo.

    2022年10月8日
    3
  • IIC通信协议详解[转载][通俗易懂]

    IIC通信协议详解[转载][通俗易懂]IIC的基本介绍IIC的简介IIC(Inter-IntegratedCircuit)总线是一种由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。它是半双工通信方式。IIC总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此IIC总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输…

    2022年5月31日
    104

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号