gpt4 book ai didi

C#/窗体 : ShowDialog and subsequent Show on Form

转载 作者:行者123 更新时间:2023-11-30 22:40:36 25 4
gpt4 key购买 nike

由于我认为与此处无关的原因,我有一个或多个与单个实例 UI(表单)通信的线程。

在工作线程中,我需要报告进度或输入数据或简单的选择。所有这些都来自用户与 UI 的交互,当然,对于 M$ .NET,所有 UI 都在主线程中运行。

显然,我需要处理 UI(主)线程和工作线程之间的线程同步。我通过正确验证 InvokeRequired 和公司来做到这一点。

那里有无数的帖子和文章讨论了 InvokeRequiredIsHandleCreatedIsDisposed 等等的不连贯性和微妙之处,所以我不说了。

我只想说,我的 UI(它只是一个表单)应该显示为模态无模式 表单,具体取决于调用者的意愿。

一个可以只是 UI.Warn( "Warning!") 而其他可以 UI.Question( "Make a choice:", options... ).

现在考虑 M$DN 文档中的以下摘录:

Form.ShowDialog Method:

Unlike non-modal forms, the Close method is not called by the .NET Framework when the user clicks the close form button...

我从来没有注意到显示为模态的表单,但是他们的实现者说它不会被销毁,在关闭(隐藏)后可能会陷入不可使用的状态。

但确实如此!

当表单从 ShowDialog( ) 返回时,它的 Handle 就被丢弃了,因为相信当再次需要它时,ShowDialog() 将被调用并重新创建句柄。

我不知道为什么 M$ 东西需要这样做,但我只是认为我能够拥有与 modalmodeless 没有问题。 M$DN 文档没有说它被禁止(或者我喝醉了找不到它)!

好吧,最后这是一种相对简单(而且很脏)的修复方法。

var r = ShowDialog( );

// Handle thrown away aftr "ShowDialog()" supposing the
// next one will recreate it.
if ( !this.IsHandleCreated )
{
// Force "Handle" recreation here, while in the main thread,
// before any "Show()" happens.
CreateHandle( );
}

return r;

它有效,但我想知道它是否不应该是达到相同目的的任何体面的方式。(也许编程的东西不会像 .NET 那样携带任何限制祖先兼容性的包袱......)

最佳答案

你确定你没有这个落后?我创建了一个简单的空白表单用作模态对话框,然后用一个只有一个显示对话框的按钮的简单表单对其进行了测试。

public partial class Form1 : Form
{
private MyDialog theDialog;
public Form1()
{
InitializeComponent();
theDialog = new MyDialog();
}

private void button1_Click(object sender, EventArgs e)
{
theDialog.ShowDialog();
}
}

我可以毫无问题地重复显示对话框。

现在,如果我调用 theDialog.Show(),关闭它,然后尝试再次显示它,我会得到一个 ObjectDisposedException

因此,文档是正确的:ShowDialog 不会调用 Form.Close,而 Show 显然会调用。

编辑:

Form.Close 的文档告诉你如果你想防止表单被破坏你必须做什么:

You can prevent the closing of a form at run time by handling the Closing event and setting the Cancel property of the CancelEventArgs passed as a parameter to your event handler.

有了这些信息和几分钟的思考,拥有一个可以显示为模态或非模态的表单就变得微不足道了:

public partial class Form1 : Form
{
private MyDialog theDialog;
public Form1()
{
InitializeComponent();
theDialog = new MyDialog();
theDialog.FormClosing += new FormClosingEventHandler(theDialog_FormClosing);
}

void theDialog_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
theDialog.Hide();
}

private void button1_Click(object sender, EventArgs e)
{
if (theDialog.Visible)
{
theDialog.BringToFront();
}
else
{
theDialog.ShowDialog();
}
}

private void button2_Click(object sender, EventArgs e)
{
if (theDialog.Visible)
{
theDialog.BringToFront();
}
else
{
theDialog.Show();
}
}
}

关于C#/窗体 : ShowDialog and subsequent Show on Form,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5120708/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com