窗口窗体进度条不起作用
本文关键字:不起作用 窗体 窗口 | 更新日期: 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!