我的查询速度很慢。跑步后需要一段时间。我想在线程中显示进度条。我尝试使用backgroundworker。
我正在使用usercontrol,这是我的面板儿童。下图是主页。当我点击第1页时,我的dockpanel将有page_1 usercontrol。
private void button_Click(object sender, RoutedEventArgs e)
{
page1 pg = new page1();
Container_Panel.Children.Add(pg);
}
我正在尝试在打开page1 usercontrol时显示未确定的进度条。我使用这些代码。
private BackgroundWorker bw = new BackgroundWorker();
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
populate();
}));
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
prg2.Visibility = Visibility.Hidden;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
try
{
bw.WorkerReportsProgress = true;
bw.DoWork += bw_DoWork;
//bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync();
prg2.Visibility = Visibility.Visible;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
以下数据网格代码的方法
private void populate ()
{
using (SqlConnection con= new SqlConnection(connectionstring))
{
con.Open();
DataTable dt = new DataTable();
SqlCommand cmd= new SqlCommand("Select ...", con);
cmd.CommandTimeout = 0;
SqlDataAdapter _dadapt= new SqlDataAdapter();
_dadapt.Fill(dt);
con.Close();
dataGrid1.itemsSource = dt.DefaultView;
}
}
代码正常工作,我可以看到prg2(进度条)变得可见。但是直到查询结束才冻结。之后,其他进程隐藏正在工作,进度条隐藏。但我想在查询过程中使进度条不确定。
或者我可以在使用clickwindows按钮的containerpanel之外创建一个进度条。
我正在尝试解决这个问题,我尝试了太多应用但无法解决。
答案 0 :(得分:1)
试试这个
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
populate();
}
private void populate ()
{
using (SqlConnection con= new SqlConnection(connectionstring))
{
con.Open();
DataTable dt = new DataTable();
SqlCommand cmd= new SqlCommand("Select ...", con);
cmd.CommandTimeout = 0;
SqlDataAdapter _dadapt= new SqlDataAdapter();
_dadapt.Fill(dt);
con.Close();
bw.ReportProgress(90,dt.DefaultView);
}
}
实施报告进度事件
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if(e.ProgressPercentage == 90)
{
dataGrid1.itemsSource = (DataView)e.UserState;// don't remember if it's the same property but there's a property check
}
}
答案 1 :(得分:1)
您应该使用任务,因为不需要后台工作程序。此外,您还需要使用async / await,以便在不影响UI的情况下正确更新Visibility。
另请注意,不需要con.Close(),因为它已经包含在using语句中。
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
{
try
{
prg2.Visibility = Visibility.Visible;
dataGrid1.itemsSource = await GetDataAsync();
prg2.Visibility = Visibility.Hidden;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private Task<DataView> GetDataAsync()
{
return Task.Run(()=>
{
using (var con = new SqlConnection(connectionstring))
{
con.Open();
var dt = new DataTable();
var cmd= new SqlCommand("Select ...", con);
cmd.CommandTimeout = 0;
var dadapt = new SqlDataAdapter();
dadapt.Fill(dt);
return dt.DefaultView;
}
});
}
答案 2 :(得分:0)
private BackgroundWorker bw = new BackgroundWorker();
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
populate();
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
prg2.Visibility = Visibility.Hidden;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
try
{
bw.WorkerReportsProgress = true;
bw.DoWork += bw_DoWork;
//bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
prg2.Visibility = Visibility.Visible;
bw.RunWorkerAsync();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void populate ()
{
using (SqlConnection con= new SqlConnection(connectionstring))
{
con.Open();
DataTable dt = new DataTable();
SqlCommand cmd= new SqlCommand("Select ...", con);
cmd.CommandTimeout = 0;
SqlDataAdapter _dadapt= new SqlDataAdapter();
_dadapt.Fill(dt);
con.Close();
Application.Current.Dispatcher.Invoke(new Action (() =>
{
dataGrid1.itemsSource = dt.DefaultView;
}));
}
}
答案 3 :(得分:0)
您可以使用nuget中的Xceed BusyIndicator控件,输入
Install-Package Extended.Wpf.Toolkit
在程序包管理器控制台上。在View参考中添加控件
<wpfex:BusyIndicator IsBusy="{Binding IsBusy}" DisplayAfter="0" BusyContent="{Binding IsBusyMessage}" />
并将其绑定到您的模型视图,无论如何您必须异步执行查询
答案 4 :(得分:0)
我会尝试这样的事情
// ##############################################################################################################################
// Properties
// ##############################################################################################################################
private BackgroundWorker _BackgroundWorker = new BackgroundWorker();
private readonly string _ConnectionString = "LoremIpsum";
// ##############################################################################################################################
// Events
// ##############################################################################################################################
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
try
{
_BackgroundWorker.DoWork += _BackgroundWorker_DoWork;
_BackgroundWorker.RunWorkerCompleted += BackgroundWorker_OnRunWorkerCompleted;
_BackgroundWorker.RunWorkerAsync();
prg2.Visibility = Visibility.Visible;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void _BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = _HardWork();
}
private void BackgroundWorker_OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
{
if(runWorkerCompletedEventArgs.Result != null)
{
dataGrid1.itemsSource = (DataView)runWorkerCompletedEventArgs.Result;
}
else
{
MessageBox.Show("Failed to load data..");
}
prg2.Visibility = Visibility.Hidden;
}
// ##############################################################################################################################
// Private Methods
// ##############################################################################################################################
private DataView _HardWork()
{
using (SqlConnection con = new SqlConnection(_ConnectionString))
{
con.Open();
DataTable dataTable = new DataTable();
SqlCommand sqlCommand = new SqlCommand("Select ...", con) {CommandTimeout = 0};
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
sqlDataAdapter.Fill(dataTable);
con.Close();
return dataTable.DefaultView;
}
}