2

单击按钮时,我有此代码应该在当前表单顶部显示一个对话框并显示文本,等待一秒钟,更改文本,然后最后关闭它:

Form p = new Form();
p.ShowDialog();

p.Text = "Start.";
Thread.Sleep(1000);

p.Text = "Counting.";
Thread.Sleep(1000);

p.Text = "End.";
Thread.Sleep(1000);

p.Close();

但是,一旦它执行p.ShowDialog();它就会停止代码,直到表单 p 关闭并且它不能按我的预期工作。我可以得到一些指导吗?不一定是解决方案,但至少也许我可以搜索一些关键字?

更新:由于我在尝试访问与问题无关的业务逻辑时遇到的困难,我正在延迟提供工作示例。请继续关注并抱歉:)

解决方案:我所做的实际上是用来Show()代替ShowDialog(). 由于我无法从业务逻辑访问表单,BackgroundWorker 派上用场并在它们之间使用。我不能分享任何代码或项目结构的布局,但总而言之,接受的答案的主要陈述是解决方案的关键:)

4

4 回答 4

3

这就是 ShowDialog() 的意义所在。它创建一个模态表单,并且在您完成之前不会将控制权返回给调用函数。如果它不需要是模态的,那么使用 .Show()。如果确实需要模态,则将代码放入 Form Load 方法中以根据需要更新文本。

于 2012-08-10T13:38:50.513 回答
2

http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx

取自上面的链接:

When this method is called, the code following it is not executed until after the dialog box is closed.

如果您想在表单中显示您想要显示的任何内容,您应该在表单本身内编写代码,在表单显示事件的事件处理程序中执行此操作。

于 2012-08-10T13:39:04.307 回答
2

正如您所发现的,ShowDialog是一个阻塞方法,在对话框关闭之前不会返回。您更改文本和处理延迟的代码需要在对话本身内。

但是,值得注意的是您会发现的下一个问题:如果您Thread.Sleep(1000)从 UI 线程调用,您的应用程序将在 1 秒内无响应。这可能不是你的目标!我建议您查看TimerorBackgroundWorker类以更顺利地处理此问题。

于 2012-08-10T13:40:20.420 回答
1

看一下这个:

public partial class Form2 : Form
{
    delegate void SetTextCallback(string text);
    delegate void CloseFormCallback();

    public Form2()
    {
        InitializeComponent();

        new Thread(DoMagic).Start();
    }

    public void DoMagic()
    {
        this.SetText("Start.");

        Thread.Sleep(1000);

        this.SetText("Counting.");
        Thread.Sleep(1000);

        this.SetText("End");

        Thread.Sleep(1000);

        this.CloseForm();
    }

    private void CloseForm()
    {
        if (this.InvokeRequired)
        {
            CloseFormCallback c = new CloseFormCallback(CloseForm);
            this.Invoke(c);
        }
        else
        {
            this.Close();
        }
    }

    private void SetText(string text)
    {
        if (this.label1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.label1.Text = text;
        }
    }
}
于 2012-08-10T13:53:14.887 回答