Closing a wpf window created on a different thread from the background worker WorkRunCompleted

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-11 21:14:03

问题


Hi there is a follow up to another question here

Here is the summary

In 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 finished

Any 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 is

How 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 code

here is my code

I 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;

    }

回答1:


Do the Background in the progress page
If 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();
        }
    }

}


来源:https://stackoverflow.com/questions/19362040/closing-a-wpf-window-created-on-a-different-thread-from-the-background-worker-wo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!