【问题标题】:Show "please wait" message box显示“请稍候”消息框
【发布时间】:2012-09-12 09:57:05
【问题描述】:

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

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());
    }
}

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

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 并行化可从 .NET 4.0 开始。
    • 不客气。顺便说一句,答案很好 - 我只是想确保 OP(或其他阅读者)知道他们可以使用 4.0 开始的 Parallel 东西:)
    • 感谢 Randolf R-F 的创意。但是您是否有与我的情况类似的 BackgroundWorker 应用程序的示例编码?
    • @Coolguy 点击BackgroundThread 下的链接,您会找到带有完整示例的官方文档,包括对后台线程的取消支持。
    【解决方案2】:

    您必须准备一个后台工作人员并使用 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();
        }
    

    【讨论】:

    • 我已经尝试过您的 Hamid 编码,但表单部分存在一些问题。我的 Form1 已经是带有按钮的主要 winform。我想要做的是,当我单击一个按钮时,它才会开始传输协议。所以,是 'Form1 msgForm;'对吗?
    • 创建新的 Windows 窗体并在其中设置标签(如果您需要取消按钮),然后使用它而不是 Form1。这个新表单将像 MessageBox 表单一样使用
    • 谢谢哈米德。我为“请稍候”消息创建了一个 Form2。但这里还有另一个问题。当我单击传输协议按钮时,它不会运行。它显示“请稍候”消息一秒钟,然后自行关闭。没有传输任何协议。怎么了?
    • 在 void bw_DoWork(object sender, DoWorkEventArgs e) 中写下您的检查代码
    • 我试过了,如果你把 try{}catch{} 语句放在 void bw_DoWork 中,它似乎无法运行。它只会在我取出 try{}catch{} 语句后运行。
    【解决方案3】:

    最简单的方法是使用 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();
    

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

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

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

    【讨论】:

    猜你喜欢
    • 2022-08-16
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 2014-05-12
    • 2011-05-12
    • 2016-06-17
    • 1970-01-01
    • 2015-08-16
    相关资源
    最近更新 更多