C# 在C语言中管理对话框窗体#

C# 在C语言中管理对话框窗体#,c#,forms,dialog,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()它停止代

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

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就派上了用场,并在它们之间使用。我不能分享任何代码或项目结构的布局,但总而言之,公认答案的主要陈述是解决方案的关键:)

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

摘自上面的链接:

调用此方法时,它后面的代码直到对话框关闭后才会执行。


如果您想让窗体显示您想显示的内容,您应该在窗体内部编写代码,然后在窗体显示事件的eventhandler中执行此操作。

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

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

查看以下内容:

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;
        }
    }
}

您确实应该使用invoke在表单内和单独的线程中编写代码。在单独的注释中,不要使用对话框。他们只是邪恶的。:)查看是否可以在父窗体的某个空白区域显示相同的消息。这样对用户来说就不那么烦人了,代码也很容易编写!你能就我的回答提供一些反馈吗?谢谢是的,对不起,我周末没有工作:)@AndriusNaruševičius跟进:别忘了将帮助您解决问题的答案标记为正确。您将无法将此代码放在模式形式中,或者运行此代码(如果不是模式),因为这将涉及在UI线程中睡眠。在这两种情况下,您都需要切换到使用
计时器或类似工具。这对我不起作用,因为根据数据的不同,我需要从父窗体进行调用并动态执行。所以我不能把它放在形式2中的线程中。我很确定有一个解决方法,但似乎我试图实现的目标不需要线程,因为简单的show而不是showdialog似乎已经解决了这个问题。明天我会更新更多信息。感谢您努力帮助我:)@AndriusNaruševičius我可以修改它以从父窗体获取动态消息。但是,我不知道如何在不使用其他线程的情况下显示窗体并关闭它。任何人,如果您已经设计了解决方案,请与我们分享=)