我编写了一个代码,用于将文本文件中的值传输到数据表。由于记录数量很多,我已经实现了一个进度条来查看状态。但它会抛出一个名为
的错误“'1'的值对'值'无效。'值'应介于。之间 '最小'和'最大'。“
您能否帮我在循环中成功实施进度条。这是我使用的代码:
我已经使用backgroundworker更新了我的编码。但它会抛出一个名为:
的错误“创建窗口句柄时出错”
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog thisDialog = new OpenFileDialog();
DataTable dt = new DataTable();
DataRow dr = null;
if (thisDialog.ShowDialog() == DialogResult.OK)
{
textBox1.Text=thisDialog.FileName;
string file1 = textBox1.Text;
//background worker
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
}
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
backgroundWorker1.CancelAsync();
}
using (System.IO.StreamReader file = new System.IO.StreamReader(file1))
{
string line=String.Empty;
int lineno = 0;
while ((line = file.ReadLine()) != null)
{
if (line.Contains("DISKXFER"))
{
string dataLine = line.ToString();
string[] split = dataLine.Split(',');
int result = split.Length;
if (lineno == 0)
{
for (int x = 0; x < result; x++)
{
DataColumn dcss = new DataColumn(x.ToString(), Type.GetType("System.String"));
dt.Columns.Add(dcss);
}
if (dt.Rows.Count <= lineno)
{
dr = dt.NewRow();
dt.Rows.Add(dr);
}
dr = dt.Rows[lineno];
for (int x = 0; x < result; x++)
{
dr[x+1] = split[x];
}
}
else
{
if (dt.Rows.Count <= lineno)
{
dr = dt.NewRow();
dt.Rows.Add(dr);
}
dr = dt.Rows[lineno];
for (int x = 0; x < result; x++)
{
dr[x+1] = split[x];
}
}
lineno += 1;
}
}
}
}
dataGridView1.DataSource = dt;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string line;
string file1 = textBox1.Text;
using (System.IO.StreamReader file = new System.IO.StreamReader(file1))
{
int count = 0;
while ((line = file.ReadLine()) != null)
{
if (line.Contains("DISKXFER"))
{
backgroundWorker1.ReportProgress(count);
}
count += 1;
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
答案 0 :(得分:2)
如果您希望应用程序在循环中时不处于“无响应”状态,则可以使用后台工作程序。不过要小心。文件对话框必须在线程外部,以免出现任何跨线程异常!将文件路径保存到私有字段,并在后台工作程序中使用它。每次存储一行,然后使用ReportProgress以更新进度条!! 获取有关使用Background Worker的示例:
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
private BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
if (bw.IsBusy != true)
{
bw.RunWorkerAsync();
}
if (bw.WorkerSupportsCancellation == true)
{
bw.CancelAsync();
}
private void bw_DoWork(object sender, DoWorkEventArgs e){ }
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){ }
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e){ }
修改强>
private string file1;
private DataTable dt;
private int iTotalLinesOfFile;
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog thisDialog = new OpenFileDialog();
if (thisDialog.ShowDialog() == DialogResult.OK)
{
if(dt==null)
{
dt== new DataTable();
}
else
{
dt.Clear();
}
file1 = thisDialog.FileName;
textBox1.Text=file1;
iTotalLinesOfFile = System.IO.File.ReadAllLines(file1).Length;
//background worker
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync(); //when you call this the DoWork will start and the code will continue!!
}
//do not let the user to click the button again!!
button1.Enabled = false;
//you will use this code if you want to cancel the job that Worker does.
//if (backgroundWorker1.WorkerSupportsCancellation == true)
//{
// backgroundWorker1.CancelAsync();
//}
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DataRow dr = null;
using (System.IO.StreamReader file = new System.IO.StreamReader(file1))
{
string line=String.Empty;
int lineno = 0;
int count = 0;
while ((line = file.ReadLine()) != null)
{
if (line.Contains("DISKXFER"))
{
backgroundWorker1.ReportProgress(count);
string dataLine = line.ToString();
string[] split = dataLine.Split(',');
int result = split.Length;
if (lineno == 0)
{
for (int x = 0; x < result; x++)
{
DataColumn dcss = new DataColumn(x.ToString(), Type.GetType("System.String"));
dt.Columns.Add(dcss);
}
if (dt.Rows.Count <= lineno)
{
dr = dt.NewRow();
dt.Rows.Add(dr);
}
dr = dt.Rows[lineno];
for (int x = 0; x < result; x++)
{
dr[x+1] = split[x];
}
}
else
{
if (dt.Rows.Count <= lineno)
{
dr = dt.NewRow();
dt.Rows.Add(dr);
}
dr = dt.Rows[lineno];
for (int x = 0; x < result; x++)
{
dr[x+1] = split[x];
}
}
lineno += 1;
}
count += 1;
}
}
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
dataGridView1.DataSource = dt;
button1.Enabled = true;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int iCount = e.ProgressPercentage;
if(iTotalLinesOfFile==0) return;
//progressBar1.Value must not be less than 0 and more than 100
progressBar1.Value = (iCount / iTotalLinesOfFile) * 100;
}
答案 1 :(得分:1)
progressBar1.maximum目前设置为零!
选项1:定义progressBar1的最大值。
progressBar1.Maximum = File.ReadAllLines(“file.txt”)。Length;
选项2 :使用Endlessprogressbar来达到目标。
编辑:包含已更正的选项1的代码:
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog thisDialog = new OpenFileDialog();
DataTable dt = new DataTable();
DataRow dr = null;
progressBar1.Minimum = 0;
progressBar1.Step = 1;
progressBar1.Visible = true;
if (thisDialog.ShowDialog() == DialogResult.OK)
{
textBox1.Text=thisDialog.FileName;
string file1 = textBox1.Text;
progressBar1.Maximum = File.ReadAllLines(file1).Length;
using (System.IO.StreamReader file = new System.IO.StreamReader(file1))
{
string line=String.Empty;
int lineno = 0;
while ((line = file.ReadLine()) != null)
{
if (line.Contains("DISKXFER"))
{
string dataLine = line.ToString();
string[] split = dataLine.Split(',');
int result = split.Length;
if (lineno == 0)
{
for (int x = 0; x < result; x++)
{
DataColumn dcss = new DataColumn(x.ToString(), Type.GetType("System.String"));
dt.Columns.Add(dcss);
}
if (dt.Rows.Count <= lineno)
{
dr = dt.NewRow();
dt.Rows.Add(dr);
}
dr = dt.Rows[lineno];
for (int x = 0; x < result; x++)
{
dr[x+1] = split[x];
}
}
else
{
if (dt.Rows.Count <= lineno)
{
dr = dt.NewRow();
dt.Rows.Add(dr);
}
dr = dt.Rows[lineno];
for (int x = 0; x < result; x++)
{
dr[x+1] = split[x];
}
}
progressBar1.Value = dt.Rows.IndexOf(dr);
Application.DoEvents();
lineno += 1;
}
}
}
}
dataGridView1.DataSource = dt;
}
正如其他人已经指出的那样:背景工作者会是一个更好的选择。特别是如果您的UI仍需要响应。
答案 2 :(得分:0)
简单地说,在你指定它时,数据表中没有行,因此最大值为0.
progressBar1.Maximum = dt.Rows.Count;
无论如何,由于您似乎事先并不知道行数,因此在显示任何“进度”时没有任何意义,因为在扩展最大值时它总是会满的。但是,您可以使用选框模式。或者事先用你要添加的行数初始化最大值。
答案 3 :(得分:0)
您应该将ProgressBar.Maximum
和ProgressBar.Minimum
属性设置为您想要的范围。
此属性获取或设置控件范围的最大值和最大值。其默认值为0
和100
。
对于Minimum
属性;
此属性指定Value属性的下限。什么时候 Minimum属性的值更改,ProgressBar控件 重新绘制以反映控件的新范围。当值 Value属性等于Minimum属性的值 进度条是空的。要更改进度条的值,请使用 使用PerformStep方法的Step属性,使用Increment 方法,或直接设置Value属性的值。