Окно ожидания в приложении Windows - PullRequest
1 голос
/ 08 октября 2008

Мне нужно показать окно ожидания пользователю. Для этого я поместил две отдельные формы окна в приложении. Первая форма - это основная форма с кнопкой. Второй - пустой с просто текстом метки. По нажатию кнопки в Form1 я делаю следующее

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

Моя идея здесь - показать пользователю окно ожидания в течение 2 секунд. Но когда я делаю это, форма 2 загружается не полностью, из-за чего метка в ней пуста Пожалуйста, дайте мне знать ваши комментарии по этому вопросу.

Ответы [ 6 ]

3 голосов
/ 17 июня 2011

Вот класс ящика ожидания, который я использую. Вот как вы это используете:

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();
                    }
            }
    }
3 голосов
/ 08 октября 2008

Это потому, что вы, вероятно, выполняете некоторые длительные операции в одном и том же потоке (потоке пользовательского интерфейса). Вы должны выполнить свой код в новом потоке (см. Класс Thread) или, по крайней мере, периодически вызывать Application.DoEvents изнутри длительной операции для обновления пользовательского интерфейса.

2 голосов
/ 08 октября 2008

Когда вы используете Thread.Sleep, вы отключите цикл сообщений Windows и запретите окну самому рисовать.

Вы можете вызвать перерисовку:

f.Refresh();

Или еще лучше использовать таймер с обратным вызовом.

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

Чтобы пользователи не могли щелкнуть в исходном окне, вы можете открыть новую форму в виде диалога:

f.ShowDialog();
1 голос
/ 08 октября 2008

Вы в основном блокируете поток пользовательского интерфейса.

Я предлагаю вместо этого, чтобы ваш конструктор Form2 (или, возможно, обработчик события Load) запустил таймер, который сработает через две секунды. Когда таймер срабатывает, закройте форму. В течение этих двух секунд поток пользовательского интерфейса будет свободен, поэтому все будет отображаться правильно, и пользователь сможет перемещать окно и т. Д.

0 голосов
/ 08 октября 2008

Я думаю, вы должны просто использовать

f.ShowDialog(this);

Затем управление возвращается при закрытии f.

Используя режим сна, вы блокируете поток пользовательского интерфейса от обновления на 2 секунды. (Нить спит).

0 голосов
/ 08 октября 2008

Можно (всегда следует для потоков пользовательского интерфейса) использовать Thread.Current.Join (2000) вместо Thread.Sleep (2000).

...