在C#中管理对话框表单

时间:2012-08-10 13:36:17

标签: c# forms dialog

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

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关闭,并且它没有像我预期的那样工作。我可以得到一些指导吗?不一定是解决方案,但至少可能是我可以google的一些关键词?

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

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

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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.

如果你想表单显示你想要显示的内容,你应该在表单内部编写代码,在表单show event的事件处理程序中执行此操作。

答案 2 :(得分:2)

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

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

答案 3 :(得分: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;
        }
    }
}