2012-08-10 53 views
2

点击一个按钮我的代码是在当前窗体顶部显示对话框并显示文本,等待一秒,更改文本然后关闭它:管理C#中的对话框表单#

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关闭并且它不能按我的意图工作。我能得到一些关于这方面的指导吗?不一定是解决方案,但至少可能有一些关键字我可以谷歌?

更新:由于我面临的困难,我正在尝试访问业务逻辑,这与问题无关,我推迟提供工作示例。敬请关注和遗憾:)

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

+1

你真的应该从表单中,并使用调用 – 2012-08-10 13:38:11

+0

在一个单独的说明单独的线程执行的代码,不使用对话框。他们只是邪恶的。 :)看看你是否可以在你的父母表单的某个空白区域显示相同的信息。这样,对用户和代码的刺激就不那么容易了! – Mayank 2012-08-10 13:43:38

+0

您能否就我的回答提供一些反馈?谢谢! – 2012-08-10 16:55:45

回答

3

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

+0

您将无法将此代码放在模态窗体中,或者在代码不是模态的情况下运行此代码,因为它会涉及到在UI线程中的睡眠。无论哪种情况,您都需要切换到使用“定时器”或类似的功能。 – Servy 2012-08-10 13:57:00

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.

如果要形成显示无论是你想显示你应该写代码的形式里面本身,做在形式表演事件的事件处理中。

2

正如你所发现的,ShowDialog是一个阻塞方法,直到关闭对话框才会返回。您的代码来改变文本和处理延迟需要在对话本身。

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

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

这不适用于我,因为根据数据,我需要从父窗体调用并动态执行此操作。所以我无法把它放在Form2中的线程中。我很确定有一个解决方法,但似乎没有必要对我想要实现的线程进行线程化,因为简单的show而不是showdialog似乎已经解决了这个问题。明天我会更新更多的信息。感谢您的努力,试图帮助我:) – 2012-08-12 20:36:12

+0

@AndriusNaruševičius我可以修改它从父窗体获取动态消息。但是,我不明白你将如何显示表单并在不使用其他线程的情况下关闭它。任何人,如果你已经设计了一个解决方案,与我们分享=) – 2012-08-13 01:40:51