在Windows应用程序中等待窗口

时间:2008-10-08 07:20:09

标签: c# .net .net-2.0

我基本上需要向用户显示一个等待窗口。为此,我在应用程序中放置了两个单独的窗口表单。第一个表单是带有按钮的主窗体。第二个是空的,只有一个标签文本。单击Form1中的按钮,我执行以下操作

Form2 f = new Form2();
f.Show();
Thread.Sleep(2000);
f.Close();

我的想法是向用户显示等待窗口2秒钟。但是当我这样做时,表格2没有完全加载,因为其中的标签是空白的。请告诉我你的意见。

6 个答案:

答案 0 :(得分:3)

那是因为你可能在同一个线程(UI线程)中做了一些冗长的操作。您应该在新线程中执行代码(请参阅Thread类)或至少从冗长的操作中定期调用Application.DoEvents来更新UI。

答案 1 :(得分:3)

这是我使用的Waiting Box类。以下是您使用它的方式:

using WaitingBox;
ShowWaitingBox waiting = new ShowWaitingBox("Title Text","Some Text so the user knows whats going on..");
waiting.Start();
//do something that takes a while
waiting.Stop();

以下是WaitingBox的代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;



    namespace WaitingBox
    {
            public class ShowWaitingBox
            {
                    private class WaitingForm:Form
                    {
                            public WaitingForm()
                            {
                                    this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
                                    this.label1 = new System.Windows.Forms.Label();
                                    this.progressBar1 = new System.Windows.Forms.ProgressBar();
                                    this.tableLayoutPanel1.SuspendLayout();
                                    this.SuspendLayout();
                                    // 
                                    // tableLayoutPanel1
                                    // 
                                    this.tableLayoutPanel1.ColumnCount = 1;
                                    this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
                                    this.tableLayoutPanel1.Controls.Add(this.progressBar1, 0, 0);
                                    this.tableLayoutPanel1.Controls.Add(this.label1, 0, 2);
                                    this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
                                    this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
                                    this.tableLayoutPanel1.Name = "tableLayoutPanel1";
                                    this.tableLayoutPanel1.RowCount = 3;
                                    this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
                                    this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29F));
                                    this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
                                    this.tableLayoutPanel1.Size = new System.Drawing.Size(492, 155);
                                    this.tableLayoutPanel1.TabIndex = 0;
                                    // 
                                    // label1
                                    // 
                                    this.label1.Anchor = System.Windows.Forms.AnchorStyles.Top;
                                    this.label1.AutoSize = true;
                                    this.label1.Location = new System.Drawing.Point(209, 92);
                                    this.label1.Name = "label1";
                                    this.label1.Size = new System.Drawing.Size(73, 13);
                                    this.label1.TabIndex = 3;
                                    this.label1.Text = "Please Wait...";
                                    // 
                                    // progressBar1
                                    // 
                                    this.progressBar1.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
                                    this.progressBar1.Location = new System.Drawing.Point(22, 37);
                                    this.progressBar1.Name = "progressBar1";
                                    this.progressBar1.Size = new System.Drawing.Size(447, 23);
                                    this.progressBar1.TabIndex = 2;
                                    // 
                                    // WaitingForm
                                    // 
                                    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                                    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                                    this.ClientSize = new System.Drawing.Size(492, 155);
                                    this.Controls.Add(this.tableLayoutPanel1);
                                    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
                                    this.Name = "WaitingForm";
                                    this.Text = "Working in the background";
                                    this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.WaitingForm_FormClosing);
                                    this.Load += new System.EventHandler(this.WaitingForm_Load);
                                    this.tableLayoutPanel1.ResumeLayout(false);
                                    this.tableLayoutPanel1.PerformLayout();
                                    this.ResumeLayout(false);
                            }

                            private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
                            private System.Windows.Forms.ProgressBar progressBar1;
                            private System.Windows.Forms.Label label1;

                            private void WaitingForm_Load(object sender, EventArgs e)
                            {
                                    progressBar1.Style = ProgressBarStyle.Marquee;
                                    this.BringToFront();
                                    this.CenterToScreen();
                            }

                            private void WaitingForm_FormClosing(object sender, FormClosingEventArgs e)
                            {
                            }

                            internal void SetLabel(string p)
                            {
                                    label1.Text = p;
                            }
                    }
                    private WaitingForm wf = new WaitingForm();
                    private string title, text;
                    private Thread waiting;
                    public bool IsAlive
                    {
                            get
                            {
                                    return waiting.IsAlive;
                            }
                            set { }
                    }
                    public ShowWaitingBox(string Title, string Text)
                    {
                            this.title = string.IsNullOrEmpty(Title) ? "Working in the Background..": Title;
                            this.text = string.IsNullOrEmpty(Text) ? "Please wait..." : Text;
                            waiting = new Thread(new ThreadStart(Show));

                    }

                    public ShowWaitingBox()
                    {
                            waiting = new Thread(new ThreadStart(Show));
                    }

                    private void Show()
                    {
                            wf.Show();
                            wf.Text = this.title;
                            wf.SetLabel(this.text);
                            while (true) {

                                    wf.Refresh();
                                    System.Threading.Thread.Sleep(50);
                            }
                    }
                    public void Start()
                    {
                            waiting.Start();
                    }
                    public void Stop()
                    {
                            waiting.Abort();
                    }
            }
    }

答案 2 :(得分:2)

当您使用Thread.Sleep时,您将禁用Windows消息循环并阻止窗口自行绘制。

你可以强制重画:

f.Refresh();

或者更好的是使用带回调的计时器。

Timer t = new Timer();
t.Interval = 2000;
t.Tick += delegate { Close(); t.Stop();};
t.Start();

要阻止用户点击原始窗口,您可以将新表单作为对话框打开:

f.ShowDialog();

答案 3 :(得分:1)

你基本上阻止了UI线程。

我建议您使用Form2构造函数(或可能的Load事件处理程序)启动一个计时器,该计时器将在两秒后触发。当计时器触发时,关闭表格。在这两秒钟内,UI线程将是空闲的,因此一切都将正常显示,用户将能够移动窗口等。

答案 4 :(得分:0)

我认为你应该使用

f.ShowDialog(this);

然后当f关闭时返回控制权。

通过使用sleep,您阻止UI线程更新2秒。 (线程处于休眠状态。)

答案 5 :(得分:-1)

你可以(对于UI线程总是应该)使用Thread.Current.Join(2000)而不是Thread.Sleep(2000)。