winform用show实现showdialog的模态化效果
一、Show与ShowDialog
众所周知在c#中有两种显示窗口的方式:模态显示(showdialog)与非模态显示(show),模态显示会阻塞调用窗口的所有消息响应,在调用ShowDialog方法后,直到关闭对话框后,才执行此方法后面的代码 ,期间用户是无法对该窗口外的界面进行ui交互的;非模态显示则不会,可以在弹出窗口和调用窗口之间随意切换。调用窗口调用show方法后,下面的代码可以立即执行。
二、实现不阻塞的等待
那么如果我们想实现一个新的窗口显示方法,既可以像模态显示那样,在关闭对话框的时候才执行显示方法后的代码,又可以像非模态显示那样不阻塞消息响应,不影响用户的UI操作。这里我们就要用到一个方法Dispatcher.PushFrame
想深入了解的可以参考这篇文章:https://www.h3399.cn/201709/148010.html
下面直说代码使用
首先需要引入WindowBase类库,然后
DispatcherFrame _dispatcherFrame = new DispatcherFrame();
Form1 Window = new Form1();
Window.Show();
Dispatcher.PushFrame(_dispatcherFrame);
这样就达到了伪阻塞,后面的代码不会执行,但又不影响其他UI操作。但一般这种会引起其他问题,需注意,因为之所以要下面代码不执行,肯定是需要form返回的结果的,用户能做UI操作了,就会有很多可能,比如退出程序,新打开窗体等,可能会导致错误。
结束伪阻塞,代码如下:
在窗体的关闭事件中添加如下代码即可
_dispatcherFrame.Continue = false; _dispatcherFrame = null;
到此代码就结束了。至于原理,想看详细的看上面的链接中的文章,这里我也简单总结下:
就是Dispatcher.PushFrame用于开启一个新的window消息while循环,这样阻塞了ui主线程,用这个新开启的window消息循环处理用户的UI操作,而DispatcherFrame我认为算是一个控制器,它的Continue属性能退出消息循环,回到主线程的window消息循环中。
所以这个方法也算阻塞了主线程,新开一个window消息队列处理用户操作。