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

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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 点击关闭当前页面

    点击关闭当前页面

  • cifar10数据集下载及图片格式解析

    cifar10数据集下载及图片格式解析CIFAR-10是由Hinton的学生AlexKrizhevsky和IlyaSutskever整理的一个用于识别普适物体的小型数据集。一共包含10个类别的RGB彩色图片:飞机(a叩lane)、汽车(automobile)、鸟类(bird)、猫(cat)、鹿(deer)、狗(dog)、蛙类(frog)、马(horse)、船(ship)和卡车(truck)。图片的尺寸为32×32×3,数据集中一共有50…

  • pycharm html注释快捷键_python一键注释

    pycharm html注释快捷键_python一键注释pycharm中同时注释多行代码快捷键:1、选中要注释的代码,然后Ctrl+’/’具体效果:importmatplotlib.pyplotaspltdata_dir=’D:/Python/neuralnetwork/CIFAR10-Guoqingxu/data/’BATCH_SIZE=2image_batch,label_batch=read_cifar10(data_d…

  • eagle-eye介绍

    eagle-eye介绍简介淘宝现在是一个由很多个应用集群组成的非常复杂的分布式系统。这些应用里面主要有处理用户请求的前端系统和有提供服务的后端系统等。这些应用之间一般有RPC调用和异步消息通讯两种手段,RPC调用会产生一层调一层的嵌套,一个消息发布出来更会被多个应用消费,另外,应用还会访问分库分表的数据库、缓存、存储等后端,以及调用其他外部系统如支付、物流、机彩票等。请试想一下,现在淘宝一个买家点击下单按…

  • 如何实现自定义类加载器_开发者不可以自定义类加载器

    如何实现自定义类加载器_开发者不可以自定义类加载器为什么要有类加载器类加载的过程初识类加载器类加载机制自定义类加载器为什么要有类加载器我们知道java中所有的二进制文件,最后都是要放在jvm中解释运行的。纯粹的二进制文件,其实并没有什么卵用。jvm在第一次使用或者预加载时,都要将某个类的二进制文件加载进去,这时候不可避免的需要用到一个加载的触手,就是这个类加载器啦。类的加载过程简单来说,一般可分为加载、连接、初始化三个过程。加载,顾名思义

  • Kali换源

    采用国内源来解决下载速度慢的问题。步骤:打开终端在终端,利用vim编辑器打开source.list文件,输入代码“vim/etc/apt/source.list”进入source.list文件,1是原本官方源(利用#注销官方源),(插入模式下输入清华源)2和3是我更换的清华源。源地址清华源:debhttp://mirrors.tuna.tsinghua.edu.cn/kalikali-rollingmaincontribnon-freedeb-src

发表回复

您的电子邮箱地址不会被公开。

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