[Winform]在Form里显示模态对话框ModalDialog
|
在Form里显示模态Dialog
问题
如何在WinForm的一个Form里面弹出一个模态Dialog?
背景
程序的框架是Winform,只有一个窗口MainForm。MainForm里面是一个TabControl,每个TabPage是一个Form,每个TabPage的Form相互独立,互不干扰,TabPage间可以随时切换。由于有某些需求,TabPage需要接受用户输入,并等待输入完成,才能执行后面的代码,此时,程序是需要阻塞等待输入的,所以需要弹出一个模态Dialog。
- 为什么不用MessageBox呢?因为MessageBox是直接弹出一个模态对话框且该对话框是一个新的窗口,这时候整个MainForm是伪阻塞状态,用户无法通过与MainForm的其他区域交互,包括点击标签页切换到其他TabPage。所以,我需要该对画框只在Form里显示。
- 为什么不用MDI呢? 最主要的原因是TabControl里的Form,其TopLevel属性是false的,如果想在Form里面添加MDI窗口,需要将Form的TopLevel属性设置为true,这时我将无法使用TabControl。
代码实现
创建一个CustomDialog类,继承Form类
- public class CustomDialog : Form{
- }
复制代码 创建CustomDialog成员变量
- 这里使用到了两个类, Panel和ControlContainer。其中Panel充当CustomDialog的容器。ControlContainer则是Panel的容器。
- public class CustomDialog : Form{
- private Panel? _panelContainer;
- private ControlContainer? _parentContainer;
- private Form? _parentForm;
- // 声明Panel,ControlContainer和Form
- }
复制代码 定义一个ShowDialog方法
要显示模态Dialog,当然要是实现ShowDialog方法啦!这里定义了一个ShowDialog方法,和其他ShowDialog方法有些许不同,该方法的参数是ControlContainer类型, 用于接收一个控件作为父控件- public class CustomDialog : Form{
- public void ShowDialog(ControlContainer parentControl){
- //TODO
- }
复制代码 设置CustomDialog.PaneContainer的属性和内容
这部分代码最主要实现了CustomDialog在它的父控件Form中显示的功能,PS:有点简单粗暴,但是有效(_)- public class CustomDialog : Form{
- private void AddDialogToTheView(){
- if(ContainerControl is null){
- throw new NullReferenceException(nameof(_parentContainer));
- }
- //panel的高度
- int panelHeight = 350;
- int panelWidth = 500;
-
- //panel显示的位置
- int startUpLocationX = (_parentContainer.ClientSize.Width - panelWidth) / 2;
- int startUpLocationY = (_parentContainer.ClientSize.Height - panelHeight) / 2;
-
- // 设置_panelContainer的属性
- _panelContainer = new Panel(){
- Height = panelHeight,
- Width = panelWidth,
- Location = new Point(startUpLocationX, startUpLocationY),
- };
- // 设置Dialog的属性
- TopLevel = false;
- DockStyle = DockStyle.Fill;
- //添加进Panel里面
- _panelContainer.Controls.Add(this);
- Contianer.Controls.Add(_panelContainer);
- // 显示Dialog
- Show();
- PanelControl.BringToFront();
-
- }
- }
复制代码 实现伪阻塞
要说实现这个CustomDialog哪里最难,应该是这个伪阻塞功能最难。前面的View相关的方案,一般人稍微思考一下都可以想出来。但是想优雅的实现CustomDialog的伪阻塞功能,确实不易
- public void WaitForExit(Cancellationtoken token){
- while(!toke.IsCancellationRequested){
- Application.DoEvents();
- }
- }
- CancellationTokenSource source = new CancellationTokenSource();
- WaitForExit(source.Token);
- //user cancel
- source.Cancel();
复制代码 这个写法有效,但还是不够优雅
来源:https://www.cnblogs.com/echo-sama/archive/2023/12/28/17932701.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|
|
|
发表于 2023-12-28 15:05:07
举报
回复
分享
|
|
|
|