C# WPF 在数据网格填充期间冻结进度条



我有一个慢查询。跑步后需要一段时间。我想在线程期间显示进度条。我尝试为此使用后台工作者。

我正在使用用户控件,这是我的面板子级。 下图是主页。当我单击第 1 页时,我的 dockpanel 将具有page_1用户控件。

主窗口

private void button_Click(object sender, RoutedEventArgs e)
{
page1 pg = new page1();
Container_Panel.Children.Add(pg);
}

我试图在打开 page1 用户控件时显示不确定的进度条。我为此使用这些代码。

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(进度条)变得可见.但它一直冻结到查询结束。之后,另一个进程隐藏正在工作,进度条正在隐藏。但是我想在查询期间使进度条不确定。

或者我可以在容器面板之外制作一个进度条,该进度条正在单击主窗口按钮。

我正在尝试解决此问题,但我尝试了太多的应用程序,但无法解决。

您应该为此使用任务,因为不需要后台工作人员。此外,您需要使用 async/await,以便在不影响 UI 的情况下正确更新可见性。

还要注意的是,缺点。不需要 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;  
}
});
}

试试这个

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
}
}
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;
}));
}
}

可以使用 nuget 中的 Xceed BusyIndicator 控件,键入

Install-Package Extended.Wpf.Toolkit 

在包管理器控制台上。在视图引用中并添加控件

<wpfex:BusyIndicator IsBusy="{Binding IsBusy}" DisplayAfter="0" BusyContent="{Binding IsBusyMessage}"  />

并将其绑定到模型视图,无论如何您必须异步执行查询

我会尝试这样的事情

// ##############################################################################################################################
// 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;
}
}

最新更新