C# 显示“请稍候”消息框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12505768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:28:41  来源:igfitidea点击:

Show "please wait" message box

c#winforms

提问by Coolguy

I want to show a 'please wait' message box while my main form is doing a lengthy task. As for my case, the lengthy task is transmitting serial protocol. Below is my code:

当我的主窗体正在执行一项冗长的任务时,我想显示一个“请稍候”消息框。至于我的情况,冗长的任务是传输串行协议。下面是我的代码:

public void transmitprotocol()
{    
    try
    {
         MessageBox.Show("Please wait. Uploading logo.", "Status");

         // Transmitting protocol coding here. Takes around 2 minutes to finish.

    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.ToString());
    }
}

I've tried the above method using MessageBox like the above coding, but I always have to close the MessageBox only it will start transmitting protocol. Is there any method I can do to still show the 'please wait' MessageBox while it transmit protocol?

我已经尝试过使用 MessageBox 像上面的编码一样的上述方法,但我总是必须关闭 MessageBox 只有它会开始传输协议。有什么方法可以在传输协议时仍然显示“请稍候”MessageBox?

回答by Erre Efe

You will need to do the expensive operation on a background thread. For that, use either a BackgroundWorkeror the new Parallelization Library (.NET 4 and so on).

您将需要在后台线程上执行昂贵的操作。为此,请使用BackgroundWorker或新的并行化库(.NET 4 等)。

Actually you need to close the dialog because it blocks the execution until you, well, close it. What you do is that you start the operation, then show the dialog and then, once the operation is done, you close the dialog.

实际上,您需要关闭对话框,因为它会阻止执行,直到您关闭它为止。您要做的是开始操作,然后显示对话框,然后在操作完成后关闭对话框。

Now, if you're using WPF I will strongly suggest you to don't use a Dialog Box and instead use a Busy Indicator, it's free, pretty easy to use and not so ugly as the Message Box.

现在,如果您使用 WPF,我强烈建议您不要使用 Dialog Box 而是使用Busy Indicator,它是免费的,非常易于使用,而且不像消息框那么难看。

EDIT: Now that you specify you're using WinForms, then go ahead, implement the background worked and, why not, a transparent window without chrome whose purpose is to show a Busy label. Once the background worker ends you close that window.

编辑:既然您指定您使用的是 WinForms,那么继续,实现背景工作,为什么不,一个没有 chrome 的透明窗口,其目的是显示一个 Busy 标签。一旦后台工作人员结束,您关闭该窗口。

enter image description here

在此处输入图片说明

回答by Hamid

You have to prepare a backgroundworker and use a windows form instead of MessageBox. Something like this as simple as copy/paste:

您必须准备一个后台工作人员并使用 Windows 窗体而不是 MessageBox。像这样简单的复制/粘贴:

    Form1 msgForm;
    public void transmitprotocol()
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        //you can use progresschange in order change waiting message while background working
        msgForm = new Form1();//set lable and your waiting text in this form
        try
        {
            bw.RunWorkerAsync();//this will run all Transmitting protocol coding at background thread

            //MessageBox.Show("Please wait. Uploading logo.", "Status");
            msgForm.ShowDialog();//use controlable form instead of poor MessageBox
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        // Transmitting protocol coding here. Takes around 2 minutes to finish. 
        //you have to write down your Transmitting codes here
        ...

        //The following code is just for loading time simulation and you can remove it later. 
        System.Threading.Thread.Sleep(5*1000); //this code take 5 seconds to be passed
    }
    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //all background work has complete and we are going to close the waiting message
        msgForm.Close();
    }

回答by Tom The Teacher

The easiest way to do this is to open the splash with show() Open the desired form and pass it an instance of the splash form in the constructor:

最简单的方法是使用 show() 打开飞溅打开所需的表单,并在构造函数中将飞溅表单的实例传递给它:

        Wait myWaitDialog = new Wait(); //Wait is your splash
        myWaitDialog.Show();
        myWaitDialog.Refresh(); //Otherwise screen fails to refresh splash
        ScheduleClassForm myForm = new ScheduleClassForm(myWaitDialog);
        myForm.TopLevel = true;
        myForm.ShowDialog();

Add this code to your resulting form constructor:

将此代码添加到生成的表单构造函数中:

    public ScheduleClassForm(Form WaitWindow)
    {            
       InitializeComponent();
       WaitWindow.Close();
    }

For me it failed in the form_load but worked in the constructor. Make sure your work is done (e.g. db load) prior to closing the WaitWindow.

对我来说,它在 form_load 中失败,但在构造函数中工作。确保在关闭 WaitWindow 之前完成您的工作(例如 db load)。