Strange problem here. I have a Login form, which opens a Registration form when the user clicks a button:
Register registration = new Register();
registration.Show();
At which point, this second form opens in front of the Login form - both windows are open and not minimized, which is fine. However, when the user completes registration and the registration is successful:
if (success)
{
this.Close(); //('this' being the Registration form)
}
The registration form closes (good), but then the Login form minimizes and I'm not sure why. Ideally I'd like the form to stay open the entire time rather than have to click the taskbar icon to display it on-screen again.
I imagine there's more to it than the code I supplied so happy to provide more if needed. Just not sure where the issue would lie.
I've now had the same problem, which even occured when using ShowDialog(). I did some research and after taking quite some time figuring out what it was, I found that setting FormBorderStyle to System.Windows.Forms.FormBorderStyle.FixedToolWindow (or SizableToolWindow) in the main form makes this happen. I also experienced (and can reproduce) a similar issue where even the child form can get minimized if it has FixedToolWindow set, so the only "real" solution for me is to not use this borderstyle on any form.
Changing this to any other FormBorderStyle value gets rid of this issue completely, although then you obviously cannot use this borderstyle anymore.
Leaving this answer here in hopes to help other people who stumble upon this very same problem, as it apparently still exists in 2019.
Although I don't know why this happens (it shouldn't), ShowDialog() should be the better option here anyway.
You can also try showDialog(this)
Related
The Questions:
Has anyone seen invoking of one modal dialog from another modal dialog cause the modality to get undone?
If you wanted to make a call with ShowDialog so that you get back a result, but without it being modal (other Forms still respond), how would you do it? (We're not trying to do that... but if there is a way to do that, maybe we're doing that accidentally.)
The Details:
We have implemented our own Print dialog that has buttons that bring up the standard PrintDialog, the standard PageSetupDialog, and the standard PrintPreviewDialog. And the printing is all done with our own PrintDocument class derived from the standard PrintDocument class. So, we're trying to follow the standard practices... we just have a few extra settings that we need the user to start with.
We invoke our Print dialog from a menu using ourPrintDialog.ShowDialog(mainWindow). When it comes up, it is properly modal (all other windows are non-responsive... in particular, that mainWindow). From that Print dialog, there are buttons to invoke each of the other three dialogs... and all are invoked with ShowDialog(ourPrintDialog), making that first Print dialog as its parent. In the case of the PrintDialog and the PageSetupDialog, they come up modal (mainWindow and ourPrintDialog and all other windows are non-responsive). And when we OK or Cancel those, it returns to the first Print dialog (ourPrintDialog) which is still modal (no other windows respond).
However, in the case of the standard PrintPreviewDialog, although we invoke it the same way (ShowDialog with the first dialog as its parent), it comes up not entirely modal. Our main window becomes responsive again. So, you can start manipulating the underlying document that the Print dialog is in the process of printing... which of course violates many assumptions. And when you close the Preview dialog, returning to the original Print dialog, it is also now not in a modal state... the main window is still responding.
We have tried doing this in a plain test app, and it works fine... the modality is not broken when going into the PrintPreviewDialog. So, it seems to be some specific interaction between the PrintPreviewDialog (since it doesn't happen with the other two) and our app's main window (since it doesn't happen with the test app). Any suggestions on what that might be? (And hence my two questions above.)
Thanks in advance for any suggestions!
Not sure why it's happening , but you might try running Spy++ on the windows and watch the messages that flow, might give you a clue as to what is happening between the windows, or the properties of the windows in question.
When I minimze form while running in Visual Studio, everything works fine - form is hidden and restored to previous FormWindowState.
However, when running outside of the IDE, suddenly form starts closing. I attached to running process, however I wasn't able to determine cause of this.
Edit: Cancelling form closing within FormClosing event doesn't even prevent form from closing when I minimalize form.
Update: It seems that hiding form causes closing it. Beacuse, if I don't hide form when user minimizes it, it won't close.
This is much more weird, since in IDE it works as expected.
Environment
Windows XP SP3 x32
Visual Studio 2005 Standard
Device/Platform: Honeywell Dolphin 9500 with Windows Mobile/Pocket PC 2003
NET Framework 1.1 and .NET Compact Framework Framework 1.0 SP3
Goal
I currently have an application with 3 forms. The first form is something like a splash screen but I have not yet decided whether or not the user will be allowed to reopen it. The second form is an aggregate listing of items that will be displayed, one by one, in the third form.
I would like to be able to open the first form and wait for a button press. When that button is pressed, I would like to open another form and dispose of the first. Once an item is selected out of the list box on the second screen, I would like to display the third form and possibly dispose of the second form. The user also needs to be able to reopen the second form to select another item to be displayed on the third form. That being said, I probably don't want to dispose of the second form. However, memory is an issue on this device (64MB shared between storage and system memory) hence my desire to dispose of things when I can.
Problem
You can probably guess this by the title, but when I close/dispose of my first form, the entire application closes. Now that I have read up on the matter a little, I am aware that this has to do with this line: Application.Run(new Form1()); or whatever my form happens to be named.
Things I Have Tried
this.Dispose() - closes the entire application
this.Close() - closes the entire application
I also saw multiple people recommending one instantiate their form (Form f1 = new MyForm();), show it (.Show();), and then use Application.Run(); with no arguments. When I try this, I get "No overload for method 'Run' takes '0' arguments"
ApplicationContext does not exist in version 1.1 of the .NET Framework
Code
static void Main()
{
Application.Run(new Welcome());
}
private void btnBegin_Click(object sender, EventArgs e)
{
Form wof = new WorkOrderForm();
wof.Show();
wof.BringToFront();
// Here is where I would like to dispose of the Welcome form
}
You can call Application.Run() with your "main" form, this will still allow the application to close properly when the form closes, but hide it (Visible=false) whilst you show the splash screen, or just show the splash screen on top of it.
Create a hidden form that you pass to Application.Run(). When you decide it's time for the app to go down, close that hidden form.
I keep answering my own questions...
I posted this identical issue on the MSDN forums and was told to use the ApplicationContext object instead of a new Form object as a parameter in Application.Run. I am going to try that now. For now I will leave this unanswered.
EDIT: Well, I recant. Application context does not exist in the .NET Framework v1.1
EDIT2: Actually, it seems that it does (http://msdn.microsoft.com/en-us/library/system.windows.forms.applicationcontext(VS.71).aspx), however it does not appear to exist in the Compact Framework version 1.0 SP3.
Is it required to have 3 forms?
One way is to create 3 panels in 1 form and just show the active panel.
I am asking this, because i want to know if when we are running an app, for start if we have an window to authenticate like a Log In window, after validating the user, can we open the Main Window in the same Thread without creating a new one?
I am trying to do this in WPF, but i think that is same thing in WPF or in Windows Forms.
Yes, you can.
Just do it.
When you generate a Windows Forms application via the IDE, it will generate the code for one form, as well as a Main function that displays the form at runtime. You can rewrite the Main method so it displays one form modally then displays the next form.
But there's a simpler way to achieve your objectives:
Have two windows: your Main window, where most of the work is done, and the login screen.
In the OnLoad event of your main window, create an instance of your login window and call ShowModal() on this instance.
If the login fails, then exit the application.
This question does not offer enough context to tell you how to do this in your specific case. In general you can just Close() a window, construct a new one and call Show() on it.
You should make sure the Application.ShutdownMode does not kill off your application when the window is closed though.
Some of our non-technical users are having problems where a dialog MessageBox in our application can sometimes be displayed behind the main form and the application does not accept any input until the messagebox (which they can't see) is dismissed.
The application is written in C# and the message boxes are standard eg the code can be as simple as MessageBox.Show(message, caption) and the messageboxes can be created by the main UI thread (ie not some background thread). The Application does not have to be run full-screen, but 90% of our users do run it full-screen.
Most of the time ((maybe > 99%) the messageboxes display correctly and I have never managed to see how it goes wrong, but I have seen a machine when it has gone wrong.
One thing I did notice is that if you have an application which displays a dialog box, then when you look at your taskmanager, you normal only see one entry in the application list. Whenever the messagebox is hidden, you will see two entries, one for the main application and another entry for this message box.
It is easy enough to fix the problem once you know what has happened, but some of our non-technical users are confused by it and end up switching off their computers. (And the ones who are using Remote Desktop are even more confused when that doesn't solve the problem).
I do not think it is related to the operating system as I have seen it happen in Vista and have been told it also happens in a terminal session on a Windows 2003 server.
Does anything know why this is happening and more importantly if anything can be done to avoid it?
Some overloads of the MessageBox.Show() method take an IWin32Window parameter as the first argument. If you pass in your Form as that first argument it should prevent this from happening.
Is it always the same message box (for the same message?) coming the same form?
Ideally, you should try to find some way to reproduce the problem at will, or at least automatically. This will make your debugging easier and you can then be sure that your future change will have fixed the bug, rather than have to wait for a few weeks for the feedback from your users.
If it is always the same message and in the same window, resulting from the same action, and if the MessageBox call is reasonably easy to trigger from an user point-of-view and if your UI is relatively standard, you could automate the UI with an AutoIT script and have it run in a loop until the problem happens.
And/or, you could create a "debug"-build of your applications that you could give it to some users (preferably the ones that seem to run into the problem the most often) that would write the contents of a StackFrame object to a log file or something similar everytime before calling a MessageBox (you could create a wrapper around the MessageBox to make this easier).
Then, when one of your users gets the problem, you can look at the log file and see where it came from (source code file, line, calls stack etc). You could also compare this to the logs from other users and see if, everytime, the MessageBox comes from the same location or if it varies.
This would show you where the problematic MessageBox is called from and where.
There may be easier solutions (especially if your application has a lot of assemblies) involving some .Net debugger that you would attach to your application when the problem occurs in order to see the call stack, etc, but I only did this with native applications (using OllyDbg) so far and not .Net. Others may be able to expand further on this idea...
Confirm the problem. What we do to fix it is following:
Run new Task and display the message box
In the main UI thread while task is still running - wait in the loop that does DoEvents. Something like this
UPDATED 2015-12-17.
Reproduced problem yestarday. To repo in my case - minimize the app, "wait" popup occures (in our case it happens after some idle time), then in the task bar click on the main app icon. This "hides" the popup so it is not possible to bring it on the screen. The code below was tested and solves the problem. But I still do not understand what/why it happens.
private static DialogResult ShowMessageBox(
string message,
string caption,
MessageBoxButtons buttons,
MessageBoxIcon icon)
{
var showMessageBoxTask = new Task<DialogResult>(() =>
{
var form = new Form() {TopMost = true};
var result = MessageBox.Show(
form,
PrepareMessage(message),
caption,
buttons,
icon);
form.Dispose();
return result;
});
showMessageBoxTask.Start();
while (!showMessageBoxTask.IsCompleted && !showMessageBoxTask.IsFaulted)
{
Application.DoEvents();
}
return showMessageBoxTask.Result;
}
You say "the messageboxes can be created by the main UI thread", which I assume means they aren't always created by the main UI thread. Your problem sounds like MessageBox.Show is occasionally called from another thread.
In the parent form, add this before MessageBox.Show():
this.TopMost = false;