如何让文本块中的进度条百分比起作用?

时间:2017-11-24 12:17:34

标签: c# wpf progress-bar

我有一个存储过程,可以从数据库中进行选择并填充数据网格。我试图在进度条中显示该过程。我已设法使进度条按预期工作,但我在显示进程百分比时遇到困难。我知道我错在哪里,但我只是不知道如何解决它。我将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();
    }

2 个答案:

答案 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;
    }