窗口窗体进度条不起作用

本文关键字:不起作用 窗体 窗口 | 更新日期: 2023-09-27 18:34:34

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

当我在做 .it 工作时

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

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

窗口窗体进度条不起作用

您无法看到进度,因为 UI 线程无法更新 UI,因为它正忙于加载您的文件。必须从后台辅助角色调用LoadScriptFromFile,并使 UI 线程空闲以处理事件和更新 UI。

我在项目中使用了 2 个方法(示例(:

1* Invoke(new Action((( => _ProgressBar.Visible = true((;

2* 或在_BackgroundWorker.ReportProgress(i);后使用 Application.DoEvents()

很惊讶编译器没有发出嘶嘶声......因为你需要一个额外的}。

您打开了 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。

只需使用 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;
    }

请确保将后台工作人员的"工作人员报告进度"属性设置为 True!