Timers inside a Child form - c#

If I have a form that has a timer to check for some stuff in its toolbar button and now I use this form as a child form insde another application, does the timer still run? any possible threading issue that might cause it to stop working?
The reason I am asking is that I have such a scenario and the toolbars are not updated if I open this app in another app, wanted to make see if the issue is coming from here and any possible fixes?

A System.Windows.Forms.Timer will raise its Tick event on the same thread it was created on, so if the parent application somehow blocks its main thread, the code in the Tick event will not get run until the thread clears, this might be the cause of the issue you are seeing, however, the rest of the UI should be unresponsive in that scenario as well.
A System.Timers.Timer will raise its Tick event on a seperate thread, however this will be of little use if your UI thread is being blocked anyways, since this would prevent you from updating the toolbar even if the code runs.

Related

showing status bar first to show progress

Im creating a c# windows form and ive come accross a problem.
When the window opens I am wanting to run a bit of code which can make the front console appear to freeze. The code runs fine but I want to show the status of the program in the status strip at the bottom of the page. I am running the code in the action Form.Shown. However the code does not update the status bar until everything is shown. I can change the label no problem.
How would I go about loading the window and then running the code and updating the status bar (like a background task)?
What areas would I need to look at to get this information?
You could use a BackgroundWorker to do this
Set the WorkerReportsProgress property to true and in the DoWork eventhandler raise the ReportProgress event
in the eventhandler for the ProgressChanged place your logic to update your progresbar
there is a example on msdn
You can use Multithreading to avoid freezing the forms. It means, you separate your form and the code (that you want to run in parallel) in different threads so that the form doesn't wait for the code completes. You can monitor the progress of the code via events.

WPF Animated ProgressBar in WinForms application

I have a WinForms application, and wanted to add some nice WPF controls, one of them being an 'indeterminate' progress bar.. which just animates nicely until I tell it to stop.
I have done this, and was racking my brains as to why it wasn't animating (changing the value of the progress bar).
I eventually tried showing my form (containing the ElementHost) modally, and hey presto, it animates, but I want to show the form non-modally, as I want to continue processing behind the scenes.
Is there some kind of setting that tells the ElementHost window to continue 'animating'?
Thanks
Rich.
There are many ways to do this , the simplest one is to use a backgroundworker for the lengthy task. The Backgroundworker has an event to report progress. Handle this event and in the handler change your progressbar's value. Just having an animation in the main thread while still doing work on the main thread will not work right ...
One other aproach you may try (though is not what I would recommend for a healty app) is to implement a DoEvents function and call it in the main thread when you want the progress bar to get updated ... Here is the link for the DoEvents implementation:
MSDN DoEvents sugestion
I would Strongly recommend the first approach though
As I mention in my comment above, the solution is to run the processing in a separte thread, which allows the .net Main GUI thread do its stuff, and animate the progress bar.

Showing a please wait animation while UI is populated

I'm writing a WinForms window in C# which displays about 12 ListBox and 6 ComboBox controls each with a few hundred to a few thousand items.
It takes a little while to populate these. Not a long while - just a few seconds, but it's nice for the user to have something to look at so they know the program is working away in the background while they wait.
I have a generic "Please Wait" animated borderless top-most window which appears while this happens, however I'm having trouble with the animation.
For most tasks which take a little while, I solve this in the following way:
Program.ShowPleaseWait(); // Show top-most animation
Thread t = new Thread(stuffToDo); // Run stuffToDo() in separate thread
t.Start();
While (t.IsAlive)
Application.DoEvents(); // Run message queue, necessary for animation
Program.HidePleaseWait(); // Hide top-most animation
and it works quite well. Occasionally the stuff in the thread will need to Invoke something and that sometimes causes a small hiccup in the animation, but it's generally not a big deal.
With this form, however, the entire code in the thread is UI code: populating ListBoxes and ComboBoxes. That means everything would have to be enclosed with Invoke blocks, which doesn't make any sense because then there's no point in having it run in a separate thread in the first place.
Aside from scrapping the whole worker thread for this particular case and throwing in an Application.DoEvents() every hundred or so insertions in each loop, is there anything I can do to allow the working animation to continue while the controls are populated?
Just run your animation in a second thread. You're allowed to have multiple UI threads, what's not allowed is accessing any UI object from a thread other than the one that initialized it. The new thread should accept an instance of LoadingAnimationForm (or whatever you call your animated dialog) and call Application.Run(animForm); When the main thread gets done populating everything, call animForm.Invoke(animForm.Close). Do not call any other methods on animForm from the main thread.
One possible approach is to use idle time processing for performing your populating code. So you create a dialog box class that is used to show yours waiting animation. You hook into the idle time processing event at the same time you show the waiting dialog box. Once the idle time processing has fully completed you send a message to your dialog telling it to quit.
The only complication is you need to organize your idle time event so it only performs a little work each time it is called, rather than performing all of it in one go. If you perform it all in one go then the dialog never has chance to process and show an updated wait animation.
Taken from this post:
May I add this CodeProject link?
All you need is to build, drag from toolbar and use. The LoadingCircle component works without any trouble at all. Works like a charm, you can even customize it!

Creating an instance of a form in a BackgroundWorker

I want to create a new instance of a form in a BackgroundWorker. I've noticed that when I do this, the newly launched form freezes.
Why does this form freeze? How can I get around this?
It's freezing because you're creating the form in the wrong thread - there's no event loop running in the background thread.
You should only create or touch UI elements in the UI thread. BackgroundWorker provides some hooks for this, or you can use Control.Invoke/BeginInvoke.
When a form "runs" it needs to have a thread that runs the WndProc and handles incoming messages from Windows. What you should consider doing here is using the Application.Run() method to start up your form. This will do the necessary work to make sure the WndProc is running properly, and I belive you can call this from your Background thread if necessary.

How can I flush buffer of form object properties BEFORE a Process.Start is executed?

On a button click, I make several changes to form elements (hiding some, showing some, bringing some to front, etc.). After those form element changes are made, I run an external process with a Process.Start(). However, even those those form element layout changes are sequentially coded before the Process.Start() call, they're not being executed/displayed BEFORE my Process.Start().
How do you force a flush of these layout changes that seem to be buffered?
You could try the Control.Invalidate(true) function on the control you want to be redrawn.
Here is a good post about the difference between Refresh, Update, and Invalidate
Based on the Post, I think you would want to use Refresh over Update to invalidate, then immediately update the control
Try either running the .Refresh method before the process.Start, or run Process.Start in a separate thread, such as:
System.Threading.ThreadPool.QueueNewWorkerItem(new System.Threading.WaitCallback(StartProcess));
void StartProcess(object state)
{
Process.Start(...);
}
By putting the start in a background thread, you allow .NET to update the UI before items in the background thread run. If the Process.Start is in the same thread as the UI, then the UI cannot refresh until all processes in that thread have finished running.
Found answer..
mainFormName.ActiveForm.Update();
Bang bang.

Categories