I have a window that I open up with ShowDialog(). The window will open in te center of my previous window. To close this window with background click I found the solution:
protected override void OnDeactivated(EventArgs e)
{
base.OnDeactivated(e);
Close();
}
The solution only works (look in picture the bracket on bottom) if I click outside any of my windows. But if I click on my Window(right bracket) I only get that sound and nothing happens(OnDeactivated does not proc).
Any Ideas?
Because ShowDialog prevents you from activating dialog's parent window, hence no activation change is made, hence no proccing.
You could use Show, as in non-modal way to show your dialog form, in case you don't "wait" on the calling code for the dialog to finish with some result.
If you do, there are workarounds, like a callback solution, or a how to close a WPF Dialog Window when the user clicks outside it link that #BWA pointed out.
Related
I am working on winform application where I need to display a popup. I am currently doing it with ShowDialog() method. but due to change in requirement, I want to show it as non-dialog. So I have used show() method instead of showDialog().
my popup window is using windows webBrowse control as one of its child control.
my problem is when I use showDialog() method, everthing works fine.
but when I use show() method, and close the popup (once user is done with his work), show method() somehow calling dispose method of webBrowse control and this is preventing me to relaunch same popup again and giving me "Cannot access a disposed object" error.
Is this expected behavior in show() method or webBrowse control. if yes, then how Can I resolve it.
Note: PopUp dialog box is injected in presenter using DI so cannot inject popup after every dispose.
Thanks in advance.
By using showdialog() you can not go back to your parent form, by simply using show() you can go back, that's all
With Show(), your code proceeds to the line after the Show statement. With ShowDialog(), it does not.
You could try using Hide()instead of Close().
Put this in the constructor of your dialog window (this is a WPF example)
public Window()
{
this.Closing += Window_Closing;
}
And then cancel the close event and hide the window instead like this
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
}
After that you should be able to reopen a closed window, beacuse it's not disposed but hidden. Problem with this is, that you have to manually clean the content of the window before reopening it, because otherwiese it contains the conten of the last use.
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();
I have an application (mainApp) that opens a modal dialog (collector) to ask for login details. The dialog has a cancel button and a standard close button in the top-right corner, and has FormBorderStyle = FixedDialog.
If I set collector.ShowInTaskBar = true I can right-click the dialog box in the taskbar and close it. The dialog disappears and the main app is still running. I can also right-click the whole group and choose 'Close all windows', which closes both the dialog and the application.
If I set collector.ShowInTaskBar = false I can right-click the application in the taskbar and click close, but nothing happens.
I would prefer not to show the dialog in the taskbar, but I would like the entire application to close when it is closed from the taskbar. How can I do this? If this is not possible I would settle for just closing the dialog.
Edit: the main form's FormClosing event does not get called when ShowInTaskBar = false
Does the MainForm's Closing event get fired when you click Close in the taskbar? If it does, and the app is being forced to stay open by the presence of the dialog windows, you could try programatically closing the dialog in the Closing event, and then letting the event run its course.
NOTE : This is all speculation, and it is a long time since I did any WinForms work so I may have the event names wrong.
When you close your forms that way, the message WM_SYSCOMMAND will be sent to your form window. We can catch this message with some informative params to perform according actions. Try this code:
public partial class Form1 : Form {
public Form1(){
InitializeComponent();
}
bool shownModal;//This flag will be used to determine if there is some
//modal dialog opening.
protected override void WndProc(ref Message m) {
if (m.Msg == 0x112)//WM_SYSCOMMAND
{
//SC_CLOSE = 0xf060
if (m.WParam.ToInt32() == 0xf060 &&
m.LParam.ToInt32() == 0 && shownModal)
{
//Your own code here
//You can close the main form or close the modal dialog
Close();
}
}
base.WndProc(ref m);
}
}
NOTE: You have to turn on the flag shownModal before showing your dialog and turn off after that. It's just a way to deal with it, you can try another way of your own.
You have to store reference to your login window in mainApp. Then you can write something like this:
loginWindow.Close();
which closes dialog window. This action can take place also inside loginwindow, for example user clicks button Close and window closes.
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 need a window that does not activate when I click on it but is should elsewhere react normal. By normal I mean if there is a button on it and I click on the button it should execute the click and call the click function ( or event handle or what so ever). So it should be a normal window except that it shouldn't get activated when you interact with it.
I know you can do this with a message filter or hooks but is there any window style that does this automatically?
this is for windows.
thanks!
Have you tried the WS_EX_NOACTIVATE extended window style?
A top-level window created with this style does not become the foreground window when the user clicks it. The system does not bring this window to the foreground when the user minimizes or closes the foreground window.
To activate the window, use the SetActiveWindow or SetForegroundWindow function.
Otherwise, if that doesn't do what you want, you will need to handle the WM_MOUSEACTIVATE message and return MA_NOACTIVATE.