How to refresh screen so that closed forms actually disappear - c#

I have multiple forms that popup during an intensive operation. For example, when a form popups asking user for something, and the user clicks OK, the form's graphics stay on the main screen, even though it is closed. How can I make it so that these graphics disappear completely?

I would recommend performing the heavy work in the background (using a BackgroundWorker for instance), so that the GUI thread is not blocked. That way, the forms will be able to peform screen updates while the work is going on.

It sounds like perhaps you are doing intensive processing on your main thread, which is the thread that processes events like painting windows. Instead you should spawn a separate thread for doing your computations/tasks so that your main thread can continue.
Alternatively you can call DoEvents() periodically while doing your processing to allow the form to refresh, but using DoEvents is kind of a cludge in my opinion.

You can call the Refresh() method on the main screen form, which will force a graphics repaint.

Related

WPF Animation does not animate. (Splash screen)

Background:
I'm trying to add an animation to a splash screen window in my WPF project. (Not using the actual SplashScreen control. I use a window.)
My reason for implementing the splash screen is beacuse there's a slight delay when the application is opened, due to the loading of data. Obviously, the splash screen's purpose is to aid the user experience, so the user knows the application has been executed.
Here's the idea behind my current approach:
Instantiate the splashscreen window at the beginning of the
constructor.
InitializeComponent() is called.
Close the splashscreen window.
Unfortunately, the animation in the splash screen doesn't start until after the InitializeComponent() method of the the main parent window is called; this occurs basically when I'd WANT TO close the splashscreen window anyway. Hence the animation is useless and doesn't start until it's too late.
My question:
Why does it not animate until after InitializeComponent() is called?
My current theory for why this happens is that it's because the splash
screen is being opened on the main UI thread. Am I correct?
Are there any workarounds that don't involve hijacking control of
the program and spawning the splashscreen in a new thread? (I don't want a solution that hackish)
And yes, I did browse this site for quite awhile and was unable to find a viable solution.
Processing time on the UI thread blocks the animation. No real way around it.
The best approach is to NOT spend so much time loading and blocking on the UI thread. I suggest that you could delay the loading of the data bound to your UI elements until after the initial load. That way, the InitializeComponents() should not take so long.
Basically, all your bindings should return no data to the controls until AFTER you initialize. This data initialization would preferably happen on a separate thread, and then notification would occur after the data has been loaded.
This would allow your splash screen to animate and you will have much more joy.
There are a few approaches that I've taken to handle this in the past, though #HighCore is right in the comments as well about your current problem
Use the SplashScreen class in the VisualBasic assembly
Use the WPF Splash Screen class
Regardless, these solutions boil down to threading, since the UI pipeline needs to render and you can't inherently do these things on the UI thread without blocking, particularly if you want animation.

Background work that perform UI change and modal dialog

I have a C#/WPF application that is going to perform a lot of actions, including UI modifications (it is loading a Macro), but I want to have a modal window with something moving telling to wait.
The load macro work must be performed in the main application thread, but how to I print the modal window as it must be non blocked by the macro loading but in the application thread because it is a UI thing.
Currently I put the LoadMacro in an BackgroundWorker in a Application.Current.Dispatcher.Invoke while displaying my waiting dialog. But it is not satisfying because the two fight each other to update the UI.
So how do I do it ?
You don't need to run the background worker from any dispatcher.
Load your modal window and then kick off the background worker having subscribed to it's ProgressChanged event. You can then ReportProgress on the background worker passing anything you like back to update the model window in the UserState property.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged.aspx

when my program in any process i see 'program Not Responding' and black screen - in Windows-7

when my program in any process (load csv file for example)
i see 'program Not Responding' and i see black screen - in Windows-7
in Windows-XP i dont see it
(after this the program Continues normal)
Why is this happening ?
When a long process is running, if it's running on the UI thread, that causes the application to not respond to other UI events, most notably drawing the screen. In both Windows XP and Windows 7, this will cause application to be reported as "not responding", but XP and Windows 7 handle window painting differently.
In XP, the application actually updates the screen, but in windows 7, the OS saves what the current screen looks like, then displays that on the screen using a different mechanism (for example, with Aero enabled, it actually displays the contents of the windows using textures in pseudo-3D).
In 7, this can cause applications that are not responding to display black (or the last-known screen in faded grey, depending on graphics settings) screens (because it doesn't have any up to date information). Whereas in XP, it leaves the old content up, but dragging a window over it causes shadows of the window to be displayed on the screen, because the lower window is not updating.
Update:
How do you fix it? Well, there's a bunch of different things, but if you have a method that takes a very long time:
private void SomethingThatTakesAReallyLongTime()
{
System.Threading.Thread.Sleep(30000);
}
Your event handler can look like this:
private void button1_Click(object sender, EventArgs e)
{
((Action)SomethingThatTakesAReallyLongTime).BeginInvoke(null);
}
This may not be a good idea in many cases, but it's a simple example of things you can try.
You are tying up the UI thread (main thread) for an extended period of time likely because the operation is intensive (either CPU or disk). Try moving the intensive operation (say reading file) into a second thread. This will keep the main thread (one w/ UI) responsive to the user and OS.
There are numerous methods to accomplish this. Using a BackgroundWorker is the simplest to implement. This should get you started:
http://msdn.microsoft.com/en-us/library/cc221403(VS.95).aspxr
Esesentially you will:
Create a backgroundWorker
Create an event handler for the DoWork event and wire it to DoWork.
Place the CPU intensive operation inside the DoWork event handler.
Call the RunAsync() method of the backgroundWorker (which will keep off DoWork event)
You can get more complex with providing progress and allowing user to cancel. Here is an example of loading large file:
http://msdn.microsoft.com/en-us/library/ms229675.aspx
This happens when your main thread is working on a relatively long-running task and therefore cannot repaint the screen. Thy using a worker thread to load the csv (for this example) and you shouldn't have this problem.
More than likely, it's happening because you're trying to execute a long running process on the UI thread (which blocks the UI thread so that it can't redraw the form).
You should use some form of Threading to start the long running process on a separate thread so that the UI can continue to function.

Mouse click when the application is busy

When I click on anywhere on my application when the application is busy it changes the cursor into a generic wait cursor. Is there anyway I can code it for an animated cursor?
This is because you must be doing some heavy operation on main UI thread. Do your processing in background (in separate thread).
You may use BackgroundWorker or Thread class to achieve this.
Windows will always use the generic "busy" cursor if the user tries to interact with it and your application is not responding.
The solution to this is to not do processing on the UI thread - do it on other threads, so your UI remains responsive.
If your UI is still responding, you can set a custom cursor to indicate that your application is busy processing.
if you are using the windows application in ASP.NET then there is a option realted to cursor in properties of the form(nit clearlly remember, it was like wait.cursor). You can use that to display the custom cursor at the time of processing also.

Waiting on Mainthread while continuing processing on UI

When working with console applications, Console.Readline relinquishes processing to the UI from the Main thread and only continues when an event, such as the pressing of the enter button is fired. How do I replicate this functionality (With a Window form as the UI in this case) in windows form application?
You cannot do this directly.
However, you can do it by calling Invoke, as I described here.
Use form.ShowDialog() instead of form.Show()
This will not stop the thread, but it will stop the user from doing other things in the UI until the window is closed.
Now that you have explained what you want to do...
It would be better to use a BackgroundWorker, keep the GUI active, but disabled and presenting a progress bar + cancel button, until done.

Categories