C# WinForms ShowDialog()调用任意方法

4
我正在开发一个控制台应用程序,用于创建一个表单以警示用户某个给定状态。在后续阶段,代码库将变成一个类库。
然而,现在我需要显示该表单(我想这里最好使用ShowDialog方法),然后在表单关闭之前调用任意方法。
例如,我需要显示该表单,设置标签控件的文本值,等待n秒钟,然后更改标签的值,最后关闭表单。我知道这听起来有点琐碎,但我正在尝试证明设计的可行性。
我已经看了一圈,似乎不可能实现这个功能,因为ShowDialog()要求我在调用方法/类的代码列表中关闭表单后才能继续执行。
以下是我目前的代码:
PopUpForm myForm = new PopUpForm(string messageToDisplay);
myForm.ShowDialog();
//call myForm.someMethod() here, before the form closes
//dispose of the form, now that we've no use for it
myform.Dispose();

//target method in PopUpform class
public void someMethod()
{
  lblText.Text = "Waiting for some reason";
  //wait n number of seconds
  lblText.Text = "Finished waiting. Form will now close";
  //it doesn't matter if the form closes before the user can see this.
}

看起来ShowDialog()不支持这种行为。我正在研究BackgroundWorker线程,但想知道是否有人对此有建议或遇到过类似情况。

3个回答

5

如果你想展示表单并继续工作,然后关闭它 - 你可以使用 Form.Show() 代替 Form.ShowDialog()

using (var myForm = new PopUpForm(messageToDisplay))
{
    myForm.Show(); // Show the form

    DoWork(); // Do your work...

    myForm.Close(); // Close it when you're done...
} 

然而,如果这是一个纯控制台应用程序(没有消息泵),那么这很可能不会正常工作。
其他选项是在您的Form中提供一个计时器来关闭它,或者将一个委托传递到Form中,在Show时运行您的方法,之后它可以关闭自己。
在稍后的阶段,代码库将成为一个类库。
当你这样做时,你可能想要想出一个不同的机制来提供通知。将库与特定的UI技术耦合是一个坏主意。最好让你的库只提供事件或其他通知,并允许用户提供UI/通知给用户。

然而,如果这只是一个纯控制台应用程序(没有消息泵),那么这很可能无法正常工作。我同意你的观点,目前,我正在使用窗体来展示事件引发的方式(将在最终版本中代替窗体)。我可能会考虑在其他地方添加事件并捕获它们。 - Jamie Taylor

3
如果这段代码将最终成为一个代码库,我建议不要让它自行显示任何表单。该库应生成事件或在某些情况下生成异常,可以被调用的应用程序捕获,以允许其显示表单。如果需要向用户呈现某些内部细节,则从库中公开DisplayEventData()方法。

我同意,请查看我对Reed Copsey答案的初始评论。 - Jamie Taylor

2
ShowDialog 方法创建一个"模态"窗口,通常会阻塞UI直到你关闭它(通过点击OK或Cancel)。你需要自己创建一个WinForm,可以是简单的,并为它创建一个消息泵。你可以通过调用 Application.Run(YourForm); 来运行自己的表单。
你需要使用互斥锁等方法来保持控制台线程不继续执行,而表单是打开状态的。该表单提供了你从WinForms中知道的所有方法,例如 Close,在其中你可以告诉你的控制台线程继续执行。
请参见MSDN上的此文档

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接