这是我的代码我将后台工作人员设置为 public partial class MainWindow : Window{ //Declare background workers BackgroundWorker bwLoadCSV = new BackgroundWorker(); //Declare class variables // some stuff public MainWindow() { InitializeComponent(); //assign events to backgroundworkers bwLoadCSV.WorkerReportsProgress = true; bwLoadCSV.WorkerSupportsCancellation = true; bwLoadCSV.DoWork += new DoWorkEventHandler(bwLoadCSV_DoWork); bwLoadCSV.ProgressChanged += new ProgressChangedEventHandler(bwLoadCSV_ProgressChanged); bwLoadCSV.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwLoadCSV_RunWorkerCompleted); } }我在按钮单击事件上以以下方式运行事件:private void CSV_Load_Click(object sender, RoutedEventArgs e) ///Function to read csv into datagrid /// { //Turn Cursor to wait System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor; Thread backgroundThread = new Thread( new ThreadStart(() => { ProgressDialog progressDialog = new ProgressDialog(); progressDialog.tbEvent.Text = "Loading CSV Data...."; progressDialog.progressBar1.IsIndeterminate = true; progressDialog.ShowDialog(); })); backgroundThread.SetApartmentState(ApartmentState.STA); backgroundThread.Start(); //Test connection to sql server if (CHHoursDataProvider.IsDatabaseOnline() == false) { System.Windows.Forms.MessageBox.Show("Can not establish contact with sql server" + "\n" + "Contact IT", "Connection Error"); //Set UI picture return; } //Set a control to update the user here tbLoadDgStat.Visibility = Visibility.Visible; //tbLoadDgStat.Text = "Getting data templete from Database..."; string FilePath = txFilePath.Text; if (bwLoadCSV.IsBusy != true) { //load the context object with parameters for Background worker bwCSVLoadContext Context = new bwCSVLoadContext(); Context.Site = cBChSite.Text; Context.FilePath = txFilePath.Text; Context.FileName = fileTest; Context.Wageyear = cbWageYear.Text; Context.Startdate = ((DateTime)dpStartDate.SelectedDate); Context.Enddate = ((DateTime)dpEndDate.SelectedDate); bwLoadCSV.RunWorkerAsync(Context); } }我的进度条表单progressDialog xaml和类是这个; <Window x:Class="Test_Read_CSV.ProgressDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Progress Dialog" Height="115" Width="306" Name="ProgressPopup"><Grid> <ProgressBar Height="31" HorizontalAlignment="Left" Margin="12,33,0,0" Name="progressBar1" VerticalAlignment="Top" Width="250" x:FieldModifier="public" /> <TextBox Height="23" HorizontalAlignment="Left" Margin="7,4,0,0" Name="tbEvent" VerticalAlignment="Top" Width="254" IsReadOnly="True" IsEnabled="False" x:FieldModifier="public" /></Grid> class is public partial class ProgressDialog : Window{ public ProgressDialog() { WindowStartupLocation = WindowStartupLocation.CenterScreen; InitializeComponent(); progressBar1.IsIndeterminate = true; }我的后台工作人员完成的代码是 private void bwLoadCSV_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { bwCSVLoadContext Context = e.Result as bwCSVLoadContext; Thread.Sleep(5000); if ((e.Cancelled == true)) { this.tbLoadDgStat.Text = "Canceled!"; System.Threading.Thread.Sleep(1000); System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default; tbLoadDgStat.Visibility = Visibility.Hidden; } else if (!(e.Error == null)) { //this.tbProgress.Text = ("Error: " + e.Error.Message); } else { if (Context.LoadResult == true) { this.dgCSVData.DataContext = oTable.DefaultView; btUpload.IsEnabled = true; } **//close the progressbar window some how here!!!** //On the main window this.tbLoadDgStat.Text = "Complete"; progressBar1.Value = 100; System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default; tbLoadDgStat.Visibility = Visibility.Hidden; } System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default; }解决方案在进度页中执行背景如果您需要传递(并返回)一个对象,请在Progress ctor 中进行操作.private void click(object sender, RoutedEventArgs e){ Progress progressDialog = new Progress(); progressDialog.Show(); if (progressDialog != null) progressDialog = null;}namespace BackGroundWorkerShowDialog{ /// <summary> /// Interaction logic for Progress.xaml /// </summary> public partial class Progress : Window { BackgroundWorker bwLoadCSV = new BackgroundWorker(); public Progress() { InitializeComponent(); //assign events to backgroundworkers bwLoadCSV.WorkerReportsProgress = true; bwLoadCSV.WorkerSupportsCancellation = true; bwLoadCSV.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); bwLoadCSV.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); bwLoadCSV.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted); if (bwLoadCSV.IsBusy != true) { // Start the asynchronous operation. bwLoadCSV.RunWorkerAsync(); } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; for (int i = 1; i <= 10; i++) { if (worker.CancellationPending == true) { e.Cancel = true; break; } else { // Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500); worker.ReportProgress(i * 10); } } } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled == true) { //resultLabel.Text = "Canceled!"; } else if (e.Error != null) { //resultLabel.Text = "Error: " + e.Error.Message; } else { //resultLabel.Text = "Done: " + e.Error.Message; } this.Close(); } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { this.tbProgress.Text = e.ProgressPercentage.ToString(); } }}Hi there is a follow up to another question hereHere is the summaryIn a wpf application in c# I had a long process of updating a remote database. to do this I created a background worker. However I wanted to have a window open and a progressbar run during the database update routine. All my attempts to achieve this on my main window with a progressbar set to Indeterminate failed as the "swishing" effect on my progressbar did not start to run on my main window till after my background worker thread had finishedAny with help and this article here I managed to open a new window in a different thread and run the background worker and have the progressbar "swish" properly and the background work run to completion. HOWEVER, my new question isHow do I close my progressbar window (called progressDialog) once my background work is finished?Please bear in mind that I am quite new to this and code examples would be greatly apprieciated and I THINK, but I am not certain I am going to want to close the progressbar window from the background worker RunWorkerCompleted area of codehere is my codeI set up the background worker as public partial class MainWindow : Window{ //Declare background workers BackgroundWorker bwLoadCSV = new BackgroundWorker(); //Declare class variables // some stuff public MainWindow() { InitializeComponent(); //assign events to backgroundworkers bwLoadCSV.WorkerReportsProgress = true; bwLoadCSV.WorkerSupportsCancellation = true; bwLoadCSV.DoWork += new DoWorkEventHandler(bwLoadCSV_DoWork); bwLoadCSV.ProgressChanged += new ProgressChangedEventHandler(bwLoadCSV_ProgressChanged); bwLoadCSV.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwLoadCSV_RunWorkerCompleted); } }I run the event on a button click event as;private void CSV_Load_Click(object sender, RoutedEventArgs e) ///Function to read csv into datagrid /// { //Turn Cursor to wait System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor; Thread backgroundThread = new Thread( new ThreadStart(() => { ProgressDialog progressDialog = new ProgressDialog(); progressDialog.tbEvent.Text = "Loading CSV Data...."; progressDialog.progressBar1.IsIndeterminate = true; progressDialog.ShowDialog(); })); backgroundThread.SetApartmentState(ApartmentState.STA); backgroundThread.Start(); //Test connection to sql server if (CHHoursDataProvider.IsDatabaseOnline() == false) { System.Windows.Forms.MessageBox.Show("Can not establish contact with sql server" + "\n" + "Contact IT", "Connection Error"); //Set UI picture return; } //Set a control to update the user here tbLoadDgStat.Visibility = Visibility.Visible; //tbLoadDgStat.Text = "Getting data templete from Database..."; string FilePath = txFilePath.Text; if (bwLoadCSV.IsBusy != true) { //load the context object with parameters for Background worker bwCSVLoadContext Context = new bwCSVLoadContext(); Context.Site = cBChSite.Text; Context.FilePath = txFilePath.Text; Context.FileName = fileTest; Context.Wageyear = cbWageYear.Text; Context.Startdate = ((DateTime)dpStartDate.SelectedDate); Context.Enddate = ((DateTime)dpEndDate.SelectedDate); bwLoadCSV.RunWorkerAsync(Context); } }My progressbar form progressDialog xaml and class are this;<Window x:Class="Test_Read_CSV.ProgressDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Progress Dialog" Height="115" Width="306" Name="ProgressPopup"><Grid> <ProgressBar Height="31" HorizontalAlignment="Left" Margin="12,33,0,0" Name="progressBar1" VerticalAlignment="Top" Width="250" x:FieldModifier="public" /> <TextBox Height="23" HorizontalAlignment="Left" Margin="7,4,0,0" Name="tbEvent" VerticalAlignment="Top" Width="254" IsReadOnly="True" IsEnabled="False" x:FieldModifier="public" /></Grid>class is public partial class ProgressDialog : Window{ public ProgressDialog() { WindowStartupLocation = WindowStartupLocation.CenterScreen; InitializeComponent(); progressBar1.IsIndeterminate = true; }My background worker completed code is private void bwLoadCSV_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { bwCSVLoadContext Context = e.Result as bwCSVLoadContext; Thread.Sleep(5000); if ((e.Cancelled == true)) { this.tbLoadDgStat.Text = "Canceled!"; System.Threading.Thread.Sleep(1000); System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default; tbLoadDgStat.Visibility = Visibility.Hidden; } else if (!(e.Error == null)) { //this.tbProgress.Text = ("Error: " + e.Error.Message); } else { if (Context.LoadResult == true) { this.dgCSVData.DataContext = oTable.DefaultView; btUpload.IsEnabled = true; } **//close the progressbar window some how here!!!** //On the main window this.tbLoadDgStat.Text = "Complete"; progressBar1.Value = 100; System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default; tbLoadDgStat.Visibility = Visibility.Hidden; } System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default; } 解决方案 Do the Background in the progress pageIf you need to pass (and return) an object then do so in the Progress ctor private void click(object sender, RoutedEventArgs e){ Progress progressDialog = new Progress(); progressDialog.Show(); if (progressDialog != null) progressDialog = null;}namespace BackGroundWorkerShowDialog{ /// <summary> /// Interaction logic for Progress.xaml /// </summary> public partial class Progress : Window { BackgroundWorker bwLoadCSV = new BackgroundWorker(); public Progress() { InitializeComponent(); //assign events to backgroundworkers bwLoadCSV.WorkerReportsProgress = true; bwLoadCSV.WorkerSupportsCancellation = true; bwLoadCSV.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); bwLoadCSV.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); bwLoadCSV.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted); if (bwLoadCSV.IsBusy != true) { // Start the asynchronous operation. bwLoadCSV.RunWorkerAsync(); } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; for (int i = 1; i <= 10; i++) { if (worker.CancellationPending == true) { e.Cancel = true; break; } else { // Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500); worker.ReportProgress(i * 10); } } } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled == true) { //resultLabel.Text = "Canceled!"; } else if (e.Error != null) { //resultLabel.Text = "Error: " + e.Error.Message; } else { //resultLabel.Text = "Done: " + e.Error.Message; } this.Close(); } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { this.tbProgress.Text = e.ProgressPercentage.ToString(); } }} 这篇关于关闭与后台工作程序WorkRunCompleted在不同线程上创建的wpf窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-23 08:55