首页 新闻 会员 周边 捐助

Winform中主窗体点击按钮后展示子窗体时,如何展现进度条???

0
悬赏园豆:10 [待解决问题]

Winform中主窗体点击按钮后展示子窗体时,如何展现进度条???

我的思路是:

(1)制作一个静态类,该类中主要有Start和Stop方法,其中Start方法中会在子线程中创建一个进度条(其实是一个窗体,窗体中仅有一个进度条,该进度条为圆形的,因为无法判断load加载速度);

静态类如下:

public static class CircleProcessHelper
    {
        private static Thread thread = null;

        public static void Start()
        {
            //ParameterizedThreadStart ParStart = new ParameterizedThreadStart(DoCircle);
            thread = new Thread(DoCircle);
            thread.Name = "CircleThread";
            thread.IsBackground = true;
            thread.Start();
        }

        private static void DoCircle()
        {
            CircleProcess circleProcess = new CircleProcess();
            circleProcess.Start();
            while (true)
            {
                //Thread.Sleep(500);
                System.Windows.Forms.Application.DoEvents();
            }
        }

        public static void Stop()
        {
            if (thread != null)
            {
                thread.Abort();
            }
        }
    }

 

(2)在主窗体的点击按钮中,执行静态类中的Start方法,在子窗体的load结束处执行静态类中的Stop方法,

//该方法是在点击按钮事件中执行
CircleProcessHelper.Start();


//该方法是在子窗体的Load方法的最后执行
CircleProcessHelper.Stop();

问题:

(1)使用该流程,UI还是会阻塞,进度条不会动,需要在多线程中执行

while (true)
            {
                //Thread.Sleep(500);
                System.Windows.Forms.Application.DoEvents();
            }

进度条才会执行,我认为这种方法,会影响性能?

(2)若使用Invoke触发UI线程中添加控件的方法,会特别慢,是为什么?难道是因为用Invoke吗?

(3)我的预期目标是:点击按钮后,会显示一个圆形进度条,当子窗体load事件加载完毕后,展示子窗体,进度条消失。请问高手该怎么处理?

谢谢!!!

< >
分享
所有回答(1)
0

额,废话不说,上代码

  /// <summary>
        /// 设置缓冲
        /// </summary>
        const int SW_SHOWNOACTIVATE = 4;
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern int ShowWindow(IntPtr hWnd, short cmdShow);

        /// <summary>
        /// 设置正在缓冲
        /// </summary>
        /// <param name="t">停止时间(单位:ms)</param>
        private void SettingBuffer(int t = 0)
        {
            if (t < 1000)
            {
                t = 1000;
            }
            BufferForm f1 = new BufferForm();
            f1.Show();
            f1.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false);
            System.Threading.ThreadPool.RegisterWaitForSingleObject(mre, (state, timeout) =>
            {
                Invoke(new Action(() =>
                {
                    ((BufferForm)state).Close();
                }));
            }, f1, t, true);
        }
_Vegetables | 园豆:586 (小虾三级) | 2015-12-07 10:12

能给讲一下,原理吗?谢谢!

支持(0) 反对(0) InProsperity | 园豆:194 (初学一级) | 2015-12-07 10:17

怎么使用?

支持(0) 反对(0) InProsperity | 园豆:194 (初学一级) | 2015-12-07 10:18

@逆境中成长: 怎么说呢,其实就是线程池的问题,Invoke是委托给UI线程的,虽然是系统自带的,但是怎么说呢,现在你要单开一个独立的线程,而这个线程的条件是基于UI线程的,并不是用UI线程去执行的

支持(0) 反对(0) _Vegetables | 园豆:586 (小虾三级) | 2015-12-07 10:20

@逆境中成长: BufferForm就是你设置的那个缓冲效果的窗体,这些代码发放在MainForm下面,你调用的时候直接传值就可以,SettingBuffer(3000),当然,方法内部也可以自己改么,比如设置触发条件,等等

支持(0) 反对(0) _Vegetables | 园豆:586 (小虾三级) | 2015-12-07 10:25

@_Vegetables: 

我按照你说的修改了一下,但是没有识别Invoke,怎么回事?

支持(0) 反对(0) InProsperity | 园豆:194 (初学一级) | 2015-12-07 10:26

@逆境中成长: 好奇葩,你用的是那个版本的,我这边4.0的framerword

支持(0) 反对(0) _Vegetables | 园豆:586 (小虾三级) | 2015-12-07 10:29

@_Vegetables: 我是想写一个专门的静态类,所以我放在静态类中

支持(0) 反对(0) InProsperity | 园豆:194 (初学一级) | 2015-12-07 11:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册