Windows窗体进度条不起作用?

时间:2013-10-08 10:59:36

标签: c# .net winforms

我有一个按钮。它会打开一个文件并处理一个文件。我想在处理文件时显示进度条。

当我在做。工作

public MainframeDataExchangeTool()
{
    InitializeComponent();
    _ProgressBar.Style = ProgressBarStyle.Marquee;
    _ProgressBar.Visible = false;
    _Random = new Random();
    InitializeBackgroundWorker();
}

private void InitializeBackgroundWorker()
{
    _BackgroundWorker = new BackgroundWorker();
    _BackgroundWorker.WorkerReportsProgress = true;

    _BackgroundWorker.DoWork += (sender, e) => ((MethodInvoker)e.Argument).Invoke();
    _BackgroundWorker.ProgressChanged += (sender, e) =>
    {
        _ProgressBar.Style = ProgressBarStyle.Continuous;
        _ProgressBar.Value = e.ProgressPercentage;
    };
    _BackgroundWorker.RunWorkerCompleted += (sender, e) =>
    {
        if (_ProgressBar.Style == ProgressBarStyle.Marquee)
        {
            _ProgressBar.Visible = false;
        }
    };
}

在我的按钮中单击我正在做

private void btnOpenScriptFile_Click(object sender, EventArgs e)
{
    try
    {
        loadScriptFlDlg.Filter = Constants.SCRIPT_FILE_FILTER;
        loadScriptFlDlg.FilterIndex = 3;
        loadScriptFlDlg.RestoreDirectory = true;
        loadScriptFlDlg.FileName = string.Empty;
        DialogResult objDialogResult = loadScriptFlDlg.ShowDialog();

        if (objDialogResult.Equals(DialogResult.OK))
        {
            _BackgroundWorker.RunWorkerAsync(new MethodInvoker(() =>
            {
                _ProgressBar.BeginInvoke(new MethodInvoker(() => _ProgressBar.Visible = true));
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(10);
                    _BackgroundWorker.ReportProgress(i);
                }
            }));
            EnableDisableControls("OpenScript");
            string strScriptError = LoadScriptFromFile(loadScriptFlDlg.FileName);///loading will taking time but progress bar not showing

基本上进度条在数据加载结束时显示,但在加载数据时不显示

4 个答案:

答案 0 :(得分:1)

您无法看到进度,因为UI线程无法更新UI,因为它正忙于加载您的文件。您必须从后台工作程序调用{​​{1}}并保持UI线程可以自由处理事件并更新UI。

答案 1 :(得分:0)

感到惊讶的是,编译器并没有因为你需要一个额外的东西而放弃了。

您可以打开4个级别的嵌套,但只能关闭3个。

我修改了您的代码,如下所示:

private void btnOpenScriptFile_Click(object sender, EventArgs e)
{
   try
   {
      if (objDialogResult.Equals(DialogResult.OK))
      {
         _ProgressBar.Style = ProgressBarStyle.Marquee;
         _ProgressBar.BeginInvoke(new MethodInvoker(() => _ProgressBar.Visible = true));
         for (int i = 0; i < 100; i++)
         {
         Thread.Sleep(10);
         _ProgressBar.BeginInvoke(new Action(() => _ProgressBar.Value = i));
         //Process my file here
         }
      }
   }
   Catch
   {
   }
}

为了便于阅读,我总是建议减少空行数。 我还发现'allman'样式包围是最容易调试的。

但与往常一样,每个人都是他自己的。

编辑:

OP编辑后的代码:

尝试添加:

application.doevents()

之后:

_BackgroundWorker.ReportProgress(i);

为什么呢?代码将保留在for循环中直到完成。通过执行'doevents',你告诉它在下一个循环之前进行外部更新。

如果没有'doevents',我猜你只会看到0和100。

答案 2 :(得分:0)

我在我的项目中用2个方法(例如)

1 * Invoke(new Action(()=&gt; _ProgressBar.Visible = true));

2 *或在Application.DoEvents()

之后使用_BackgroundWorker.ReportProgress(i);

答案 3 :(得分:0)

使用BackgroundWorker(bgw)完成类似的操作。

    private void MyMethod()
    {
        bgw.RunWorkerAsync(); //this calls the DoWork event
    }

    private void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        //Expensive task
        //Calculate how far you through your task (ie has read X of Y bytes of file)
        bgw.ReportProgress(myInteger);
    }

    private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        myProgressBar.Value = e.ProgressPercentage;
    }

确保将BackgroundWorker的“WorkerReportsProgress”属性设置为True!