希望是我能力有限

时间:2021-12-21 04:34:26

适用于:.net2.0+ Winform项目

配景:

有时候我们需要开一个简单的窗口来做一些事,例如输入一些对象、点选一个item之类的,可能像这样:

希望是我能力有限

完了返回原窗体并获取刚刚的输入,这样做并没有什么问题,但在几天前我俄然孕育产生了一些想法:为什么非得有板有眼的弹出一个窗体给用户呢,是不是可以在按钮相近迅速泛起一个层来做这些事呢,类似快捷菜单那样,用户开心就在里面做一下该做的事,不开心就在其它处所点一下它就消掉,原来很轻便快捷的操纵,,DUANG~弹出一个窗体来会不会令用户心里咯噔一下呢,感应熏染层面的工作往往是很微妙的,不管怎样,我既然起了这个念头,just try it。

我首先找了一下现成的方案,公然在牛逼的codeproject.com已经有牛人做了这样的工作:

希望是我能力有限

简单体验了一下,简直是了不起的缔造。道理是操作ToolStripControlHost可以承载自界说控件的这一能力,让下拉式控件ToolStripDropDown将任何自界说控件像右键菜单那样弹出来(别忘了右键菜单ContextMenuStrip就是担任自ToolStripDropDown),这样就即是把菜单作为一个容器,可以弹出任何或简单或庞大的控件组合,同时又具有菜单具有的便捷性,召之即来挥之即去。其时了解到这方案的时候真挺高兴,正是我想要的效果,觉得这下好了,不用瞎费劲本身造了。

但很快发明一个在我看来还挺在意的不敷,就是ToolStripDropDown只有Show,没有ShowDialog,就是不能以模式化(Modal,也有叫模态的,鉴于MSDN都称模式,我也随流叫它模式)的方法弹出,这是由ToolStripDropDown的固有能力决定的,该方案既然基于ToolStripDropDown,自然也受限于此,不能模式化弹出。这样带来的问题是某些情况下的挪用体验欠好(体验这种事固然不是用户才有的专利,俺们码农也是人,也要讲体验的说),好比弹出的控件是让用户输入一些对象,完了用户点击某个按钮什么的返回原窗体,然后在原窗体获取用户刚刚的输入,然后接着做后面的事。由于非模式的Show不会梗阻代码,所以就不能在Show的下方想固然的获取值、使用值~这是显然的。要想获得值可能就得特别采纳一些做法,例如响应弹出控件的*事件,或者把原窗体传入弹出控件完了在后者中做原本应该在原窗体中做的事~等等,步伐固然有很多,但这都是因为只能Show带来的多余的事,有什么比在一个要领中弹出控件、期待返回、继续措置惩罚惩罚来的爽滑的呢,像这样不是很自然吗:

string s; using (Popup p = new Popup()) { if (p.ShowDialog() != DialogResult.OK) { return; } s = p.InputText; } //go on ...

所以很遗憾,不得不挥别这个优秀的方案,造本身的*。不过受该方案的启发,我想到用ContextMenu来做容器(注意这个菜单类跟上面提到的担任自ToolStripDropDown的ContextMenuStrip大大的差别,前者是OS原生的菜单,就是在桌面、图标以及文本框中右键弹出的那种菜单,.net是通过调API的方法来操纵这样的菜单,而后者则完全是.net实现,更多信息请参考MSDN,此处不展开),因为ContextMenu的Show是梗阻式的,正合我意。但一番测验考试之后放弃,它的菜单项MenuItem不像ToolStripItem那样可以通过ToolStripControlHost承载自界说控件,但愿是我能力有限,总之我做不到把自界说控件弄到ContextMenu上,也没见过原生菜单上呈现过文本框、复选框等奇怪的对象,如果您知道怎么扩展原生菜单,还望不吝见教,先行谢过!

我还是打回.net的主意,傍边仍然是做了许多差此外测验考试,Form、Panel、UserControl、ContainerControl、Control等等看起来适合做容器层的对象都试了个遍,甚至从头在ToolStripDropDown上打主意,最后选用Form,改革一番,自我觉得较抱负的实现了我要的对象:一个叫做FloatLayerBase的基类,它自己担任自System.Windows.Forms.Form类,而需要作为浮动层显示的应用则担任自FloatLayerBase进行实现,例如下面这个接受用户输入数值的NumInputDemo实现:

样子和特点:

不会令父窗口掉去焦点(不会抢焦点的层才是好层):

希望是我能力有限

固然,男人不止一面:

希望是我能力有限

还有其它边框样式,有待用户自行体验,最后有demo供给。

可以有调解尺寸的手柄

可以点住客户区拖动

另外一些应用:

希望是我能力有限

这些都只是demo,没那么都雅和强大,重点是有了这个FloatLayerBase,就可以实现本身的浮动应用。

使用说明:

确保FloatLayerBase类在项目中~空话。源码在此: