Windows窗体:Windows标签不会呈现

时间:2016-05-24 14:44:18

标签: c# winforms

相似
MessageBox.Show("Test", "Test")

我制作了一个ProgressWindow,它在长时间运行之前显示,然后隐藏:

ProgressWindow.Show("Test","Test")
Thread.Sleep(20000);
ProgressWindow.Hide();

使用以下代码:

class ProgressWindow : Form
{
    private Label label1;

    private static ProgressWindow window;

    internal static void Show(string Message, string Caption)
    {
        window = new ProgressWindow(Message, Caption);
        window.Show();
    }

    internal new static void Hide()
    {
        (ProgressWindow.window as Control).Hide();
    }

    private ProgressWindow(string Message, string Caption)
    {
        InitializeComponent(Message, Caption);
    }

    private void InitializeComponent(string Message, string Caption)
    {
        this.label1 = new System.Windows.Forms.Label();
        this.SuspendLayout();
        // 
        // label1
        // 
        this.label1.Location = new System.Drawing.Point(50, 40);
        this.label1.Name = "label1";
        this.label1.Size = new System.Drawing.Size(300, 120);
        this.label1.TabIndex = 0;
        this.label1.Text = Message;
        // 
        // ProgressWindow
        // 
        this.ClientSize = new System.Drawing.Size(400, 200);
        this.ShowIcon = false;
        this.MinimizeBox = false;
        this.MaximizeBox = false;
        this.ControlBox = false;
        this.FormBorderStyle = FormBorderStyle.FixedDialog;
        this.StartPosition = FormStartPosition.CenterScreen;
        this.Controls.Add(this.label1);
        this.Name = "ProgressWindow";
        this.Text = Caption;
        this.TopMost = true;
        this.ResumeLayout(false);

    }
}

现在的问题是显示了我的进度窗口,但是在标签的位置,只有一个白色的盒子,没有文字。此外,如果我尝试单击该窗口,标题将从"测试"到"测试(没有回复...)"。

为什么会这样,我将如何改变它?

我怀疑线程阻塞有问题(但为什么?不应该渲染标签?)并尝试

internal static void Show(string Message, string Caption)
{
    window = new ProgressWindow(Message, Caption);
    new Thread(t => {
        window.Show();
    }).Start();
}

但这根本不显示ProgressWindow表单。

1 个答案:

答案 0 :(得分:0)

是的,问题是由于线程阻塞造成的。调用Thread.Sleep()时,当前线程无效,这意味着不处理任何Windows消息。这可以防止您的进度对话框完全显示其UI。

我不确定为什么在后台线程上调用Show()方法不起作用,但我相信WinForms要求UI线程是一个单线程公寓,默认情况下线程是Multi-螺纹公寓。

为了正确实现这一点,我建议使用BackgroundWorker类。它会自动创建一个后台线程来执行长时间运行的工作,并在工作完成后触发一次。您可以使用以下内容:

ProgressWindow.Show("Test","Test");

var worker = new BackgroundWorker();
worker.DoWork += (sender, args) => {
    // perform your long running task here, this is a background thread
    Thread.Sleep(2000);
};
worker.RunWorkerCompleted += (sender, args) => {
    // update the UI here, this is running on the UI thread
    ProgressWindow.Hide();
}
worker.RunWorkerAsync();

请注意,RunWorkerAsync()会立即返回,因此您的UI需要处理用户在后台任务完成之前可以与UI进行交互的事实。