C# Reuse Progress Bar?

Hi All,

Ok dipping my big toe into C#.Net from VBA and would like help / clarification on progress bars and the whole idea of modular programming.

I thought that if I had some-function in a dll and someother-function in someother-dll that decided to add a progress bar to both that I could potentially do this with a single progress bar...

I realise that this might be ambitious for a beginner so what if I have some-function and someother-function in the same ddl?  Is it possible to use 1  progress bar to meet the needs of both functions with a single progress bar?

So far every example that I am able to find on Progress Bars seems to have the function (typically a loop) inside the form that displays the progress bar.

My thoughts are along these lines:

Class1.Function1
Set Progress Min = 1
Set Progress Max = 100

For i = 1 to 100
    Increment Progress
Next i

Open in new window

And
ClassA.FunctionA
Set Progress Min = 1
Set Progress Max = 500

For i = 1 to 500
    Increment Progress
Next i

Open in new window

LVL 15
DrTribosAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Miguel OzSoftware EngineerCommented:
You could define the progress bar as a property of each class and then set this property before using it.
Just keep in mind that only one instance at the time can use the progress bar, if there are multiple independent instances, you will require many progress bar instances as well.

A simple tutorial is shown here but typically you use it to display progress in background tasks as shown in this example

Hope it helps,

MAS
0
DrTribosAuthor Commented:
You're a fellow Sydney-sider... :-)  

Thanks for you comments, sadly this is pitched slightly above my current skill set.  I understand what you mean by "only 1 instance" but I've no idea how to properly define the progress bar as a property of a class.  It seemed easier in VB.Net.  - but I'm confident that google will tell me if I search for this: "c# set property from another class"

But, how then do I update my progress bar in a meaningful way as I loop through my collection?  I figured it would involve an event of sorts to trigger the background worker?  

If you could provide some pseudo code showing what I should include in my loop I'd be really quite happy (although I should be mowing the lawn or something).
0
Miguel OzSoftware EngineerCommented:
A simple code to follow (that do not use  background worker as it complicates the code)
    public class MyFunction
    {
        public ProgressBar ProgressBar { get; set; }
       private int _minimum;
       private int _maximum;
        public void SetupProgressBar(ProgressBar pb, int min, int max)
        {
            ProgressBar = pb;
            ProgressBar.Minimum = min;
            ProgressBar.Maximum = max;
            ProgressBar.Step = (max - min) /100;
             _minimum= max;
           _maximum = max;
        }

        public void DoWork()
        {
            for (int i = _minimum; i <= _maximum; i++)
            {
                //Do your work here
                //ProgressBar.Value = i;  //Use this line if you want to use I, but not the step
                ProgressBar.PerformStep();//advance progress bar by step.
            }
        }
    }

Open in new window

Yep, I live at Hornsby - lovely day today, just finishing cleaning the backyard.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

DrTribosAuthor Commented:
I'm in the NorWest - just made a compost bin :-D

Thanks for the code, seems easy enough to follow, although some parts confuse me.  For example:

public ProgressBar ProgressBar { get; set; }

On this line there are 2 things called ProgressBar - I'm not sure what each of them are.  I'll try changing the name of one of them and see what breaks.

I'm not sure if I'll get a chance to test today.

Also curious about threads...  Most of what I see uses the backgroundworker, some of what I see suggests alternatives to backgroundworker (WPF?).  I'm assuming that background worker is what allows 2 threads to communicate with each other.  I'm mainly used to working with a single thread in VBA (except perhaps for some events that seem to fire off the side)  but leaving that aside, is your code based on a single thread or multi-thread?

Many thanks :-)

PS I'm guessing single thread
0
AndyAinscowFreelance programmer / ConsultantCommented:
Before you get too much into doing this just take a step back, stop and think.  WHY???????

A dll is a library of common code.  It might just number crunch, it might contain forms.  Nice and modular.  It can be reused in many places in your app, or even other apps.

A progress bar is an informative way to show progress to the user.  Part of the GUI - specific to an app.

To reuse the progress bar it implies you would somehow need to instruct the function which time intensive procedure in which dll would need to be called AND how that will communicate back (without mentioning cross-threading of GUI elements).

Think.  Is this for learning?  Is this sensible in terms of my app?  Is this going to create a lot of work and messy, hard to maintain code, for no good purpose?
0
DrTribosAuthor Commented:
Hi Andy,

I can see your point. Yes in part this is learning. But trying to get my head around the concepts. Fair enough that you say messy but I don't know enough to know that. I see a situation where I feel i should reuse a tool but don't yet understand why it is ok to recreate the userform over and over (when other code is modular).

Hope this makes sense.

Cheers
0
AndyAinscowFreelance programmer / ConsultantCommented:
Learning - anything is good, even if the end result is you learn that was a bad way to do it.  ;-)

I can understand your reasoning.  My main point is just how this one form will cope with multiple (different) procedures and how you intend to link that up.
0
it_saigeDeveloperCommented:
@DrTribos - Well first, to answer a question you had asked earlier.  In the line:
public ProgressBar ProgressBar { get; set; }

Open in new window

There are four parts.

The first part specifies the "access modifier" of the object being defined.  It is optional to include this but in cases where the "access modifer" is not included, the compiler will use the default access modifier dependent upon the defined default "accessibility level" of the declared object.  In this case since we are declaring a public object that is a member of a class.

The second part defines the type of the object.  In this case a ProgressBar type is being specified.

The third part specifies the instance name of the object.  While in c# you can reuse the type name of the object as it's instance name, you cannot use keywords as instance names.

The fourth part is used to specify the initialization of the object.  In this case, the object is initialized as an auto-implemented property.

What that basically means is that the compiler, for all intents and purposes, will take the method as is and create a backing store for it, e.g. -
public class MyFunction
{
	// I am the private field used to hold the reference and values of the ProgressBar property.
	private ProgressBar _progressBar;

	// I am the public property that exposes the private field to the outside world.
	public ProgressBar ProgressBar
	{
		get { return _progressBar; }
		set { _progressBar = value; }
	}

	// Other implementation details follow
}

Open in new window

Second, Miguel's implementation does not take threading into account.  Threading is important because, to put it simply, your application can only process one task at a time; e.g.
using System;
using System.Threading;
using System.Threading.Tasks;

namespace EE_Q28738745
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine("Even though we can write programs that can do multiple things.");
			Task.Run(() => 
			{
				Thread.Sleep(30);
				Console.WriteLine("In the end, they are still linear.");
			});
			Console.WriteLine("Multiple threads are used so that this line can appear to be processed before the line above it.");
			Console.ReadLine();
		}
	}
}

Open in new window

Which produces the following output -Capture.JPGWith this in mind, you use a different thread in order to update your progress, while the bulk of your process runs concurrently.

-saige-
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DrTribosAuthor Commented:
Hi All - thank you for all this information.  It feels like things are starting to gel...

Saige - that's a great example, gives me a lot of insight that I might have taken a while longer to stumble upon; thanks.

Andy - it seems that your comment here reflects exactly what I was setting out to achieve:
A dll is a library of common code.  It might just number crunch, it might contain forms.  Nice and modular.  It can be reused in many places in your app, or even other apps.

A progress bar is an informative way to show progress to the user.  Part of the GUI - specific to an app.
To put things in perspective I have a fairly extensive set of macros in VBA which ultimately will be rewritten in C#;  to this end I have the help of a programmer.  However, I recently faced a problem that (as far as I could tell) VBA simply unable to deal with - I struggled with VB.Net and eventually used an online code converter to to generate C#.Net from my VB.Net code and finally resolved my problem.

The syntax of VB.Net was pretty easy for me because of my VBA experience, but C# is, well, different.  

I mention this because what I have now is a large chunk of VBA 30k lines and a small chunk of C# dll that I use from VBA by declaring the function:
Private Declare Function myFunction lib "myFirstDLL.dll"....

Open in new window

So, reflecting further on your statement
A progress bar is an informative way to show progress to the user.  Part of the GUI - specific to an app.
yes that makes perfect sense to me... BUT how?!

Given the background of my project, what should I do?  Build the ProgressBar in VBA and pause my dll for a short time in each loop so my VBA GUI can update?  Is there a clear way forward?  

Right now the answer seems to be the progress bar is (should be) app specific and part of the GUI, but then your next statement makes this very pursuit seem impractical:
To reuse the progress bar it implies you would somehow need to instruct the function which time intensive procedure in which dll would need to be called AND how that will communicate back (without mentioning cross-threading of GUI elements).
I feel like I'm missing something quite fundamental - if the progress bar is part of the GUI then surely it is meant to be reused?
0
AndyAinscowFreelance programmer / ConsultantCommented:
A couple of points.
As already mentioned threading is important.  The UI runs in one thread and if you run a long running procedure in the same thread then the UI is blocked.  Obvious answer is to run the two in separate threads.  Unfortunately that then leads to cross threading errors when you try to update the progress bar (main thread) from your worker thread.  So you need some way to communicate that is thread safe and then for multiple procedures....  (Is my point becoming clearer?)

Just pausing in the long running loop does NOT allow the UI to update - because you are blocking the same thread with the pause.

>>if the progress bar is part of the GUI then surely it is meant to be reused?

Why?  Do you have just one button, one textbox.... and reuse those or do you have a number of them.

It might be sensible to do what you want but I am a bit suspicious.  Just wanting to reuse the progress bar is making me think you are saving a few minutes work but spending an extra hour to get that saving.
0
DrTribosAuthor Commented:
Hi Andy -

I think I must have misunderstood what you were driving at.  It seemed like you were saying the app specific progress bar could (/ should?) report progress for operations that might be done in some dll somewhere, and that dll could be used by other apps...

What I was getting at with my question:
>>if the progress bar is part of the GUI then surely it is meant to be reused?
was if (for want of a better expression) I 'subcontract' work out to a dll that just happens to be so useful that many of my applications use it (I'm dreaming now) then how should I report the progress that my dll is making if I feel the need to present this to the end user?
0
DrTribosAuthor Commented:
BTW - right now, this really is not an issue.  I am more than happy to modify the dll to include a userform with a progress bar.  I'm just wondering which approach is the most conventional ;-)  

Here to learn!
0
Miguel OzSoftware EngineerCommented:
Your DLL should contain only business logic and it should be UI independent. If later on in life you wold like to change UI technology or support other UIs (e.g. ASP.NET or C# Office Add-in) you can do so.
If you need to reuse UI form or components just create another class library (DLL) to contain any reusable form/component, etc. and add it as a reference to your UI solution.
The idea of the progress bar property is to give you access to the progress bar you defined in the constructor and change it half way if your code needs to do that.
NOtes:
1) Keep in mind that VBA code allows mixing of both UI and business logic, you would not like to have that in your new converted code.
2) Please try not to over engineer your solution too much or you may get burned by far too many choices.
0
DrTribosAuthor Commented:
Hi,

Thanks for your comments - unfortunately my attention has been dragged away from this. I'm keen to resume but it will be at least a week before I have the opportunity.

I'm still missing something fundamental - I guess that's what happens when you try to learn programming informally 😣😮
0
DrTribosAuthor Commented:
Hi Guys,

Thanks for your thoughts and helping me to better understand how this hangs together.  I've not had a chance to revisit this properly but hope to soon.  Appreciate your time, each comment helped.

Cheers,
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.