0

I have been trying to make sense of this article http://bensprogrammingwork.blogspot.com/2012/01/progressbar-in-wpf.html

I have the following code on my Button_Click event:

FileInfo existingFile = new FileInfo("C:\\Users\\cle1394\\Desktop\\Apple Foreign Tax Payment Sample Layout Proposed - Sample Data.xlsx");

ConsoleApplication2.Program.ExcelData data = ConsoleApplication2.Program.GetExcelData(existingFile);

The GetExcelData() method takes a few minutes to complete, so I would like to show a progress bar to indicate the estimated time until completion.

However, I don't know how to apply the methods in the tutorial above to my code below for GetExcelData():

public static ExcelData GetExcelData(FileInfo file)
{
    ExcelData data = new ExcelData();
    data.Countries = new List<Country>();

    using (ExcelPackage xlPackage = new ExcelPackage(file))
    {
        // get the first worksheet in the workbook
        ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets[1];

        List<string> countryNames = new List<string> 
        { 
            "Australia"/*,
            "China - Beijing",
            "China - Shanghai",
            "Hong Kong",
            "Hungary",
            "Ireland",
            "Spain",
            "United Kingdom"*/
        };

        List<string> monthNames = new List<string>
        {
            "January",
            "February",
            "March",
            "April",
            "May",
            "June",
            "July",
            "August",
            "September",
            "October",
            "November",
            "December"
        };

        foreach (string name in countryNames)
        {
            Country country = new Country();

            Console.WriteLine(name);

            country.Name = name;
            country.Months = new List<Month>();

            foreach (string _name in monthNames)
            {
                country.Months.Add(GetMonthDataRows(_name, GetMonth(_name, GetCountry(name, worksheet), worksheet), worksheet));
            }

            country.Totals = GetTotals(country);

            data.Countries.Add(country);

            // this is where I would like to update the progressbar

        }

    } // the using statement calls Dispose() which closes the package.

    return data;
}

I would like to update the progressbar in the foreach loop above. Can someone show me an example how to do this?

6
  • Does this answer your questions stackoverflow.com/questions/15429256/wpf-progressbar Commented Aug 13, 2013 at 13:20
  • @bhs I have seen that but I am still not sure how to do this. I would appreciate a simple example. Thanks. Commented Aug 13, 2013 at 13:21
  • BackgroudWorker ReportsProgress Commented Aug 13, 2013 at 13:24
  • @Blam I understand the concept but don't know how to apply it. Could you please show me an example using my code above? Commented Aug 13, 2013 at 13:26
  • There is a great example in MSDN msdn.microsoft.com/en-us/library/… Commented Aug 13, 2013 at 13:36

3 Answers 3

1

Copy the the following code to the bw_dowork method in the tutorial and it should work.

FileInfo existingFile = new FileInfo("C:\\Users\\cle1394\\Desktop\\Apple Foreign Tax Payment     Sample Layout Proposed - Sample Data.xlsx");

ConsoleApplication2.Program.ExcelData data =  ConsoleApplication2.Program.GetExcelData(existingFile); 

so, what they are doing is that onStart_click they they start the background async task, that is where you need to write what you are currently doing in the onClick method.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, Sayed. But I have to update the _worker.ReportProgress(i); from within ConsoleApplication2.Program.GetExcelData() and I am not sure how.
I am not sure if it would work but try passing the worker as a parameter to the GetExcelData,so that you get a reference to the worker and then try calling the worker.ReportProgress method inside it.
1

I have done a similar thing in WPF but I was wanting to show update messages in a List without blocking the UI thread see here. You could replace the List in this example with a message. Sorry, don't have time to write a simplified version of it just now.

Comments

1

In the article, you will see a BackgroundWorker object. Firstly, read about the BackgroundWorker Class on MSDN.

This object provides an easy way to perform long running actions in a separate thread. It is essential that you perform long running actions on a thread separate from the UI thread if you don't want your UI to lock up whilst the action is executing. It is irrelevant whether you use a Console application or not for this.

In the article, you will also see a ProgressChangedEventHandler which is set to a method called bw_ProgressChanged in the constructor. This bw_ProgressChanged method will be called on the UI thread so this is where you can access your UI elements, namely, your ProgressBar object.

Look now at the bw_DoWork method... this is where you... do the work (the long running action) on the other thread (created by the BackgroundWorker). Now, note the line where the BackgroundWorkwer is created from the sender parameter... this is essential because you need to use that object to call the bw_ProgressChanged method from the other thread. This is done using the ReportProgress method of the BackgroundWorkwer class.

The value that you pass as the progress value is up to you, but must be between the minimum and maximum values that you set in your ProgressBar control. The idea is that you regularly pass a value that increases each time you do a bit of work and ends at the value that you set your ProgressBar.Maximum to.

So the only connection to your example above is the GetExcelData() method which you would put in your DoWork method.

4 Comments

Thanks for your help. How do I call _worker.ReportProgress(i); from my ConsoleApplication2.Program.GetExcelData() method?
The simplest thing to do would be to move the code in your GetExcelData() method into the DoWork method, replacing the Thread.Sleep line. Then you could move the call to _worker.ReportProgress(i) inside your foreach loop perhaps? The rest is for you to work out. :)
I figured that but I was hoping there would be a more OOP approach.
There is, but it's more complicated and I don't really have enough time to explain it all to you. Basically, you could create a new class, put your GetExcelData() method in there along with a custom delegate. In the DoWork method, create a new instance of your new class and set up a local handler for the delegate. Either the delegate or the class constructor would need to take a parameter of type BackgroundWorker so that you can react when the delegate is called from the GetExcelData() method by calling _worker.ReportProgress(i)... it just adds one level of abstraction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.