I currently have a problem with forms here.
Whenever some process is ongoing, I have a progress dialog that should popup, but when I click the "X" button of the window/form behind my progress dialog, it will be dismissed and the ongoing operation is cancelled.
How can I prevent that from happening? Should I have to disable my whole form behind my progress bar? and how can I do it?
p.s.
I have tried this and this and this but NONE of them seems to work in my application. T__T
Start the form using Form.ShowDialog() instead of Form.Show(). That will disable the background form (actually any other form in the process) until the form you are showing closes. As an added benefit you can have the form return a value (e.g. Cancel, OK, Yes, No, etc.) in case any action needs to be taken as a result.
Not actually the answer you might be expecting, but you could handle the Form.FormClosing event, setting e.Cancel = True
This won't disable the Close button, but will make your form remain open in this case.
See more at: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosing.aspx
You should show the progress bar as modal dialog, please check whether this answer work for you javasript like model window on winform
HTH.
Related
Form2 is user confirmation window,i want to close the application by stop button on mainform,but currently form2 is active and there is no dependency between form2 and mainform.How to close application ?
You must be opening Form2 using ShowDialog() method. Instead of that use Show() method and on MainForm button's click event call Application.Exit() method
You can use...
// for WinForms application
if (System.Windows.Forms.Application.MessageLoop)
{
System.Windows.Forms.Application.Exit();
}
// for Console application
System.Environment.Exit(1);
So your problem is the parent window will not have focus/input until the modal window (the confirmation dialog) has finished.
So, to avoid this, just make the confirmation dialog using a custom window (instead of a common dialog / msgbox) and show it. This way if the user wants to click your main form they can (the confirmation will be on background, covered by the main window because of this).
it looks like you're showing the dialog as ShowDialog() or showing a built in MessageBox which is also a ShowDialog that needs to be closed in order for focus to return back to main window. So what you should do is create a custom Dialog and use dialog.Show() method. This will allow you to interact with your main window while the dialog is open and you can click on a button to close your application regardless of the dialog being open or not. Following code should do the closing work for you
Application.Current.ShutDown();
In my windows forms application, I close one form and open another like this:
MyApp.MySecondForm frmInst = new MyApp.MySecondForm();
frmInst.Show();
this.Hide();
But before I open like this, I set label text in my first form because I want to inform the user that second form is loading.
Imagine second form's loading takes 10 seconds, when I press the button in order to open the second button, the label text doesn't get changed until the second form gets open. When I close the second form, I recall the first form and see that the text has changed.
Which way should I follow to set label text right after user clicks a button?
Thanks in advance.
You have to call the Refresh() method before frmInst.Show(). Because the graphics will not refresh until the method is finished executing, unless you do it manually.
Are you firing that 10 second process asynchronously?
If not, that's what's causing the delay. It getting the information (10 seconds), then updating the GUI thread.
Try using a BackgroundWorker:
http://www.dotnetperls.com/backgroundworker
Should sound weird, but this is just for my hobby. I would want a (custom) messagebox to pop up with a YesNo buttons which should ideally block the code. But I should be able to click on the parent form so that I can dismiss the message box without having to specifically click on the messagebox buttons (equivalent to clicking No on the message box)..
something like this:
void Foo()
{
CustomMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo);
//block the code here, but user should be able to click on form, so that its equivalent to have clicked No;
//if clicked No, return;
//delete.
}
So the solution I thought was make the custom message box non modal - so that user can click on form, but I'm not able to block code.. How can i do that?
It would look like this:
void Foo()
{
NonModalMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo);
//block thread till user clicks on form or messagebox buttons.
//unblock when user clicks.
//if No, return;
//delete.
}
Edit: I know this is not a standard practice and I know non modal forms do not block, while modal forms do. So please do not recommend to be content with either modal form's or non-modal form's behavior. My question would be is there any way to simulate the behaviour of ContextMenu with windows forms.
You can solve this quite easily. Create and use a modal dialog but override the WndProc of the dialog and process the WM_MOUSEDOWN event. Check the position of the mouse down and if it is over the parent window but not over the dialog itself then simply dismiss the dialog.
Essentially you can't do this in a 'blocking' call easily. What you could do easily enough is to either pass the information required to perform the delete, or a delegate to perform the operation, to the form. When they click Ok you simply perform the operation. If they activate the parent form, then just close the child.
You want the user to be able to click the background window to cancel the dialog box? Add a handler to the background window so that when the user clicks on it you check to see if the non-modal window is displayed, if so close it.
Sounds easy, but you will need to be careful to handle every possible click on the background window and child windows. That sounds like a can of worms I wouldn't want to go down.
Perhaps instead you could detect if the non-modal dialog box loses focus and automatically close it. I can see this behavior making sense for a simple "confirm delete" dialog box, but as a user my first reaction is going to be to spam the ESC key to close the dialog box.
Another way of handling this is by manually enabling the parent form when calling ShowDialog, from here
[DllImport("user32.dll")]
private static extern bool EnableWindow(IntPtr hWnd, bool enable);
internal static DialogResult ShowDialogSpecial(this Form formToBeShown, Form parent)
{
parent.BeginInvoke(new Action(() => EnableWindow(parent.Handle, true)));
formToBeShown.ShowDialog(parent);
return formToBeShown.DialogResult;
}
Just call the extension method from any parent form like this:
var f = new Form();
f.ShowDialogSpecial(this);
//blocks but parent window will be active.
Of course you need to handle the clicks on parent form to close child form.
You could do something like:
public void ShowMe() {
Show();
while (!_receivedDeactivateEvent)
Application.DoEvents();
}
I'm not sure I'd recommend it, though -- I'm not sure how stable it would be, nor am I sure whether it would behave the way you want if you click the Delete button on the parent form while the 'dialog' is up (would it close the first dialog first, or leave it up? might be the latter, which could get messy).
An easier way: set form's "TopMost" property to be True. Then it will act like blocking
I have a form that requires a long operation (expansion of a treeview node searches the network for additional items to create more tree nodes) - so I plan on using a BackgroundWorker for this task. During the long operation I want the cursor to be the wait cursor and I want the entire form to be unclickable except for the Cancel button. I know I could use Enabled=false but this turns the treeview grey which looks pretty lame imo.
I could just NOT use a BW but that means I have to use DoEvents to get the cursor to change and that possibly "Not Responding" would show up, which I hate.
I thought of handling all the mouse click events and keyboard events so that they are cancelled if the BW is busy... so that is my current plan. I just wondered if I am missing something, if there is another way.
Thanks.
There is no easy way to do that. It is better to fix your treeview and use Enabled property. You can also show your progressbar in Modal dialog - that will block UI
You could use a Panel as an overlay over the form, wholly or partly transparent, which only propagates clicks when over the cancel button - similar to the way browsers simulate modal windows by 'graying' the background with an overlay.
When you are in processing mode, set the Z-Order of the mask to be in front of all other controls, and when that finishes set it behind them.
You could use Background worker and pop up another dialog with progressbar and that shows current progress and a cancel button. Where you can user
popup = new ProgressWindow();
popup.Owner=this;
popup.show();
And the cancel button will cancel the background worker. In this way your back form will not be clickable and popup will remain on top with cancel button.
i am using normal Form2.Show() and From1.Hide() to navigate the Form1 to Form2.
Application button is disappearing and appearing on the task bar while navigating just like flickering.
How to avoid this flickering?
Your approach is wrong. You should have one main form which will be showing in taskbar. And all child forms should be set ShowInTaskBar = false. When ever, button on taskbar is clicked, application should activate / minimize the current visible child. This way you wont see button changing in taskbar. But personally I dont see any issue with current flickering, it is by default and there is nothing wrong with it.