我有一个存储过程,可以从数据库中进行选择并填充数据网格。我试图在进度条中显示该过程。我已设法使进度条按预期工作,但我在显示进程百分比时遇到困难。我知道我错在哪里,但我只是不知道如何解决它。我将progressBar.Maximum
设置为dt.Rows.Count.And这就是为什么我最后获得4%的示例,因为我的数据库中有4个项目。我试过把它放在for循环中我的我在doWork中从0变为dt.Rows.Count而不是100,但这不起作用。
这是我的代码:
private void bSelect_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerAsync();
// int i = 0;
SqlConnection con = new SqlConnection(ConString);
SqlCommand cmd = new SqlCommand("tblProbaSelect", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter puname = new SqlParameter("@username", SqlDbType.NVarChar, 50);
SqlDataAdapter adapter;
DataSet ds = new DataSet();
puname.Value = tbUsername.Text;
cmd.Parameters.Add(puname);
try
{
adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
progressBar.Minimum = 0;
progressBar.Maximum = 100;
double step = (100 / ((double)dt.Rows.Count));v
/*
for (i = 0; i <= dt.Rows.Count - 1; i++)
{
progressBar.Value += 1;
Thread.Sleep(1000);
// MessageBox.Show(dt.Rows[i][0].ToString());
}*/
tabela.ItemsSource = dt.DefaultView;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
cmd.Dispose();
con.Close();
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
progressBar.Value += step;
(sender as BackgroundWorker).ReportProgress(i);
Thread.Sleep(100);
}
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
编辑:我已经设法从0到100获得百分比。但它并不是真正基于数据库查询。 我所做的更改是我将select方法放在一个函数中,我在doWork部分调用该函数。但是,我的进度值基于for值,而不是查询本身。 我的新代码:
public void selectQ()
{
SqlConnection con = new SqlConnection(ConString);
SqlCommand cmd = new SqlCommand("tblProbaSelect", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter puname = new SqlParameter("@username", SqlDbType.NVarChar, 50);
SqlDataAdapter adapter;
DataSet ds = new DataSet();
this.Dispatcher.Invoke((Action)(() =>
{
puname.Value = tbUsername.Text;
}));
cmd.Parameters.Add(puname);
try
{
adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
this.Dispatcher.Invoke((Action)(() =>
{
progressBar_Copy.Minimum = 0;
progressBar.Maximum = 100;
double step = (100 / ((double)dt.Rows.Count));
}));
this.Dispatcher.Invoke((Action)(() =>
{
// Thread.Sleep(1000);
tabela.ItemsSource = dt.DefaultView;
}));
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
cmd.Dispose();
con.Close();
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
progressBar.Value += step;
(sender as BackgroundWorker).ReportProgress(i);
Thread.Sleep(100);
}
selectQ();
}
答案 0 :(得分:1)
你需要
progressBar.Maximum = 100;
double step = (100 / ((double)dt.Rows.Count));
并在for循环内
progressBar.Value += step; //At the very last step round to 100
答案 1 :(得分:0)
在完成此操作之前,您无法了解此操作的进度。为了获得最大进度条,您必须拥有所有记录。如果你有你的所有记录,那么工作已经完成 您可以预先查询以获取行计数,然后使用DataTable.RowChanged事件来了解数据适配器何时向表中添加了新行,但是您将执行两次长时间运行操作(SQL查询),只是这样你的进度条工作不要这样做!
我建议您使用不确定的进度条并打开和关闭它的可见性。只需在xaml或后面的代码中将进度条的IsIndeterminate属性设置为true:
<ProgressBar x:Name="progressBar_Copy" IsIndeterminate="True"/>
或
progressBar_Copy.IsIndeterminate = true;
您也应该使用积木作为一次性物品。我给你写了一个样本。
void ExecuteQuery()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
progressBar_Copy.Visibility = Visibility.Visible;
worker.RunWorkerAsync(tbUsername.Text);
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
string username = e.Argument as string;
if (!string.IsNullOrEmpty(username))
{
using (SqlConnection con = new SqlConnection(ConString))
using (SqlCommand cmd = new SqlCommand("tblProbaSelect", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@username", username);
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
try
{
con.Open();
adapter.Fill(dt);
e.Result = dt;
}
catch (Exception ex)
{
e.Result = ex;
}
}
}
}
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result is Exception)
{
MessageBox.Show(((Exception)e.Result).Message);
}
else
{
DataTable dt = e.Result as DataTable;
if (dt != null)
tabela.ItemsSource = dt.DefaultView;
}
progressBar_Copy.Visibility = Visibility.Hidden;
}