Show loading form - c#

I have an application where I need to display a loading form on some actions. So, I have a button that opens a form, and when I click on this button I need to display my loading form. I use the following code:
private void diligênciasToolStripMenuItem1_Click(object sender, EventArgs e)
{
LoadingWindow loadingWindow = new LoadingWindow();
try
{
loadingWindow.Show();
Cursor.Current = Classe_Cursor.LoadCustomCursor(#"D:\Wait (1).ani");
FormConsultaDiligencia Childform = new FormConsultaDiligencia();
Childform.MdiParent = this;
Childform.Show();
Cursor.Current = Cursors.Default;
loadingWindow.Close();
}
catch (Exception ex)
{
MessageBox.Show("" + ex.Message);
}
}
When I click this button the LoadingWindow opens, but the items that I have inside the form don't work:
All appears like blank, and it would appear like:
What is happening here? I can't get there alone, can someone explain to me what is the problem?

This occurs because you show form and execute prolonged operations into GUI thread. You should execute this operations in backgroung thread.
EDIT: code removed.

After the istruction loadingWindow.Show() the click function is hang by loadingWindow that seems no filled with components.
The code restart from Cursor.Current = Classe_Cursor.LoadCustomCursor(#"D:\Wait (1).ani") after the user close the loadingWindow.
The istruction loadingWindow.Close() is an error: at that point the loadingWindow is already closed.
I guess you have to load animation and strings in constructor of loadingWindow.
Anyway I think you need to use a thread to perform the creation of Childform. At the end that thread will send a close request to loadingWindow and start to show Childform.
Solution proposed by adv12 will be your gol easely.

Related

Cursor icon doesn't change inside constructor in Windows Forms

I have an application that has the following constructor:
public BankApp()
{
InitializeComponente();
Cursor.Current = Cursors.WaitCursor;
// some coding and setting up
Cursor.Current = Cursors.Default;
}
However, the cursor icon is not set to WaitCursor, for some reason, whereas if I do any other action, it is replaced properly.
I need this because in I want to prevent the user to take any action until all routines inside the constructor are called and finished.
Any help is greatly appreciated!
Note that Cursor is a property of the form. The selected cursor displays when the mouse is moving over this form. But since the form is not yet visible when the constructor runs, the wait cursor cannot display.
Consider moving long running stuff to a Shown event handler:
private void Form1_Shown(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
try {
Thread.Sleep(2000); // Do long running stuff here
} finally {
Cursor.Current = Cursors.Default;
}
}
Instead, you could also set the wait cursor in the form which is opening this new form.
Cursor.Current = Cursors.WaitCursor;
try {
var frm = new BankApp(); // Constructor is running here.
frm.Show();
} finally {
Cursor.Current = Cursors.Default;
}
If your form is not the main form, you can use the following code to set the wait cursor for all open forms. This should also work in the constructor:
Application.UseWaitCursor = true;
try {
Thread.Sleep(2000); // Do long running stuff here
} finally {
Application.UseWaitCursor = false;
}
The try-finally ensures that the default cursor is also reset, if something should go wrong.

Button.Text is changing after Form is visible

I have a button that loads a Form, as it gets lots of data from a database and takes a few seconds, I want to advise the user to wait.
When I click the button the button text does not change.
This is the button Click code I am using:
private void btnItemConfigForm_Click(object sender, EventArgs e)
{
var itemConfigBtnText = btnItemConfigForm.Text;
btnItemConfigForm.Text = "Waiting...";
ItemConfigForm form = new ItemConfigForm();
form.Show();
if (form.Created)
{
btnItemConfigForm.Text = itemConfigBtnText;
}
}
If I Comment out
if (form.Created)
{
btnItemConfigForm.Text = itemConfigBtnText;
}
Then the button text changes to waiting after the new form window is visible.
What am I missing to get the button text to change before the form window is visible.
the simple solution is to add this row:
btnItemConfigForm.Refresh();
after this row
btnItemConfigForm.Text = "Waiting...";
Otherwise the text of the button will be changed only when the function ends, this function will redraw the form display!
P.s.
If you want the form will not be blocked - you can use in asynchronic running to the function "Show" (or New) then you will need Event to notify the first form when the form will be loaded
sorry for my English... :)
Added
btnItemConfigForm.Update();
under
var itemConfigBtnText = btnItemConfigForm.Text;
btnItemConfigForm.Text = "Waiting...";
This updates the button Control before moving on to initialising and showing the form.

How to have focus only on loading form while an event is occurring

i would like to know how can i get focus on my loading form when an event is fired. As soon as when i press the button my loading screen pops up and after couple of seconds it loosing focus.. which mean, i am able to click my main form, especially all my columns cells and stuffs How can i get rid of this??
Codes:
private void button3_Click(object sender, EventArgs e)
{
bool done = false;
//thread pool should be used under a seperate manager so that UI dont get affected
ThreadPool.QueueUserWorkItem((x) =>
{
using (var splashForm = new Form4())
{
splashForm.Show();
while (!done)
Application.DoEvents();
splashForm.Close();
}
});
move(); // move files
Datagrid_bind();
done = true;
}
If I understand your question correctly, you want the user not to be able to click on your main form while it's loading the data. If that's the case, you can simply hide your form while it loads:
myMainForm.Hide();
When it finishes loading, you call Show again:
myMainForm.Show();

how to lock the application GUI in C# Winform [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to block Winforms UI while background thread is running
i am using a C# WinForm application
I have a Save button on the screen where the data of the screen is saved to database.
what happens, when user clicks to button application goes to database and saves data.
it takes some time.
but mean while if user again click on the Save button the Click event get catched and when the first Click return to main code (after saving database) the caught event get fired..
In short the click event get caught and fired when the thread returns from the first event
( I tried the scenario of enable/disable the button).
How can I stop this behavior.
Regards,
Akhil
#Jalal: I tried this code with some modification as
private readonly object _userActivityLocker = new object();
private void btnSave_Click(object sender, EventArgs e)
{
if (System.Threading.Monitor.TryEnter(_userActivityLocker))
{
//note that any sub clicks will be ignored while we are here
try
{
DateTime dt = DateTime.Now;
Thread.Sleep(2000);
Debug.Print("FirstClick {0} Second Click {1}",dt.ToLongTimeString(), DateTime.Now.ToLongTimeString());
//here it is safe to call the save and you can disable the btn
Application.DoEvents();
}
finally
{
System.Threading.Monitor.Exit(_userActivityLocker);
//re-enable the btn if you disable it.
}
}
}
but when i rapidly click on button (i checked with 5 times rapid clicks) 5 click events
has been fired and console window is showing
FirstClick 1:30:22 PM Second Click 1:30:24 PM
FirstClick 1:30:24 PM Second Click 1:30:26 PM
FirstClick 1:30:26 PM Second Click 1:30:28 PM
FirstClick 1:30:28 PM Second Click 1:30:30 PM
FirstClick 1:30:30 PM Second Click 1:30:32 PM
The problem is that your program is dead to the world while it is saving the data to the database. The user's mouse click is sitting in the message queue, waiting for your UI thread to come back to life. When it does, the button is no longer disabled so the Click event fires.
You can solve it by emptying the message queue before you re-enable the button so the click is processed while the button is disabled:
private void button1_Click(object sender, EventArgs e) {
button1.Enabled = false;
// Save data to database
//...
System.Threading.Thread.Sleep(2000);
Application.DoEvents(); // Empty the message queue
if (!button1.IsDisposed) button1.Enabled = true;
}
Do not skip the IsDisposed test, DoEvents is dangerous because it isn't selective about what events get processed. It will happily let the user close the main window while your code is still running.
But the better solution is to not let your UI thread go dead like this. Use a BackgroundWorker to perform the save on a worker thread. This will also avoid the ugly "Not Responding" ghost window that Windows puts up when your save takes more than a couple of seconds. It probably doesn't do this yet right now, but it will a year from now when the dbase has grown. You can re-enable the button in the BGW's RunWorkerCompleted event handler.
By enabling, then re-enabling again as you eluded to. What was the problem with this?
public void SaveButton_Click(..., ...)
{
this.SaveButton.Enabled = false;
Save();
this.SaveButton.Enabled = true;
}
using a System.Threading.Monitor class will do the trick like:
private readonly object _userActivityLocker = new object();
private void btnSave_Click(object sender, EventArgs e)
{
new Thread(delegate()
{
if (System.Threading.Monitor.TryEnter(_userActivityLocker))
{
//note that any sub clicks will be ignored while we are here
try
{
//here it is safe to call the save and you can disable the btn
}
finally
{
System.Threading.Monitor.Exit(_userActivityLocker);
//re-enable the btn if you disable it.
}
}
}) { IsBackground = true }.Start();
}
To prove that changing the button to enable or disable state is not enough here a simple test:
Add a new form and add a button1 to it and inside the button1 click event handler write the following code:
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
Console.WriteLine("First Message");
Thread.Sleep(2000);
Console.WriteLine("second Message");
button1.Enabled = true;
}
and then build and run the application, double click on the button1 and the result int the output window will be:
First Message
second Message
First Message
second Message
so we have to make sure only one click is executed even when double click or so and that accomplished simply by using the System.Threading.Monitor
Update: Note that you can use a Task "if C# 4.0", a ThreadPool.QueueUserWorkItem or BackgroundWorker as a substitute of Thread.

Why can I not close a form in C#?

I cannot close one of my forms programmatically. Can someone help me?
Here's the code:
private void WriteCheck_Load(object sender, EventArgs e) {
SelectBankAccountDialog sbad = new SelectBankAccountDialog();
DialogResult result = sbad.ShowDialog();
if (result == DialogResult.Cancel) {
this.Close();
} else {
MessageBox.Show(result.ToString());
}
MessageBox.Show(sbad.bankaccountID.ToString());
}
As configurator mentioned (in comments), the form must be shown before it can be closed, so, instead of the Load event, you should be doing this in the Shown event instead.
If you don't want the form visible for the Dialog box, I guess you can wrap the event code in a Visible = false;
In summary, the basic code would be
private void WriteCheck_Shown(object sender, EventArgs e)
{
Visible = false;
SelectBankAccountDialog sbad = new SelectBankAccountDialog();
DialogResult result = sbad.ShowDialog();
if (result == DialogResult.Cancel) {
this.Close();
} else {
MessageBox.Show(result.ToString());
}
MessageBox.Show(sbad.bankaccountID.ToString());
Visible = true;
}
By calling Form.Close(), the form should close, but not until all waiting events have been processed. You also still have a chance to cancel the form closing in the FormClosing event.
First, you'll probably want to return after your call to this.Close(). If it still doesn't close, step through your code and see what is happening. You may have to set and check a "forciblyClose" flag and return from any other processing methods before it'll actually close.
The actual problem is that windows won't let a form close on it's load method. I have to show the dialog on construction, and then if the dialog result is cancel I have to throw an exception and catch the exception on form creation.
This place talks more about it

Categories