C# How to determine a status of a Form - c#

I have a tray app that starts ( Form 1 ) and shows on right click a "Login" menu strip item.
On click, I setup a Form 2, asking for user and pass.
On a successful authentication, I'd like to close Form 2 and continue with Form 1 ( ie. I would like to start a timer ).
I was thinking of just setting up a timer which would check the Form 2 status ( basically a getter function inside Form 2 ).
Still, I think there has to be an easier way than having something tick.

I dont think you need a timer or any thing for that just show the form as a Modal Dialogue and return to main form when closed.

You should show the login form using the ShowDialog method.
This method shows a modal dialog which will prevent the user from interacting with the rest of your application until the dialog is closed.
You should then perform authentication in the login form's button click handler, and close the form when it's successful.

Related

Opening a new form via label causes Error to appear

I'm trying to make a new form appear when I click on a label. I'm using Windows Application Forms.
Here's the code:
private void label1_Click(object sender, EventArgs e)
{
Form parpokeru = new Form();
parpokeru.Show();
parpokeru.ShowDialog();
}
When I click on the label, a error appears (Unhandled exception has occurred in your application...). Can anyone tell me how to fix it?
Call .Show() or .ShowDialog(). Not both.
Show() will display your second form, while still allowing the user to access the first form.
ShowDialog() will display your second form as "modal". Execution of code in the first form stops while the second form is open (at least on the main thread.. for example, timers will continue to run), and the user will not be able to access your first form while the second is open.
When you call the Show method your form is shown on video like another window and the code returns immediately from the call. So your code continues and all the forms of your application are available for the user interaction. It is calledd a modeless dialog
On the contrary, ShowDialog is a blocking call. The code doesn't return from this call until something happen inside the called form that terminates the visualization of the form. As an example comes to ming a call to the methid Hide or a click on a button with its DialogResult property set to something different from DialogResult.None. At this point the code from ShowDialog returns and the normal processing continue. While the code is blocked inside the ShowDialog the application is blocked and the user cannot interact with other forms or menus or whatever is displayed on video. It is called modal dialog
Another difference is ShowDialog returns value (a DialogResult enum value) that can can be used to determine how the user closed the form (DialogResult.Cancel, DialogResult.OK), also ShowDialog does not call the Dispose method at closing time. This will allow to retrieve property from the Modal Dialog like user inputs for further processing.
I cannot imagine what happen in the internal processing of your form if, after a modeless call to Show you call immediately a ShowDialog on the same form instance. However, an exception is really the minimum to expect from this code.

Form in C# returns DialogResult.Cancel to Parent When It is Minimized

I have a form "Main" and in Main I am creating another form which I use .ShowDialog() to display it. I do this because I don't want the rest of the code to in Main to execute until after the new form is completed. I am allowing a user to minimize the new form to system tray.
The problem: When the form gets minimized it is returning DialogResult.Cancel to the Main form that called it, causing the next line to run early.
Code to create form from Main form:
for(int i = 0; i < lvAll.SelectedItems.Count; i++)
{
this.Hide();
this.run = new RunProfile(this.profiles[lvAll.SelectedItems[i].Text]);
DialogResult result = run.ShowDialog();
MessageBox.Show(result.ToString());
}
In the new form a user will get a list of files that copy... now the user can continue and copy those files and I would expect to return a result of OK and if not I assume they are going to cancel and return Cancel...
Is my only recourse to return Abort from the new form if a user specifies a cancel and assume that a cancel is someone trying to minimize? This just seems odd
You could handle this in a number of ways, one way is like what follows:
MainTestForm mainTestForm = new MainTestForm();
if (mainTestForm.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
return;
}
You must set the DialogResult state when you close the form like
this.DialogResult = System.Windows.Forms.DialogResult.OK;
I hope this helps.
This is entirely by design. When you hide a modal dialog, the user doesn't have any way to get back to the program. Dialogs don't have a taskbar button and the rest of the windows in the app are disabled so cannot be activated. The only recourse the user would have is to kill your program with Task Manager.
So Winforms does the logical thing, it automatically closes the dialog to avoid this UI trap. And of course you'll get DialogResult.Cancel.
Use proper UI design, a dialog should always have its MinimizeBox property set to False.
I'm not sure what you are trying to achieve with that. However, to get the Dialog to return anything else, you have to set it in the form's (Dialog's) DialogResult property before the form is closed.
You may also use the Form_Closing event of the dialog to set the DialogResult property to what you want. This is done before the form closes.
Here is a quote from MSDN regarding ShowDialog:
When this method is called, the code following it is not executed
until after the dialog box is closed.
After further reading it does state the X does not close the form but hides it and so you must dispose of it:
When a form is displayed as a modal dialog box, clicking the Close
button (the button with an X in the top-right corner of the form)
causes the form to be hidden and the DialogResult property to be set
to DialogResult.Cancel. The Close method is not automatically called
when the user clicks the Close button of a dialog box or sets the
value of the DialogResult property. Instead, the form is hidden and
can be shown again without creating a new instance of the dialog box.
Because of this behavior, you must call the Dispose method of the form
when the form is no longer needed by your application.
It seems this same issues applies to minimizing a userform as well.

Close Modal Form when mouse click outside form area

I would like to close a modal form when the user clicks outside (anywhere on the computer desktop) the modal form. How can we do this as a modal form is not meant to lose focus.
You need to hook mouse (and keyboard if required) and capture their events. Then check if the click happened outside the form (and area). If yes, flag a sign which can be read by the model form that it can close down.
Algo:
Hook mouse click event.
When callback function is called, check for the click position - if it's inside your form or not (you might need to translate the locations to Desktop locations - I hope you know how to!)
If the point is outside the form, set a flag (boolean or anything that makes you happy). Make sure the form can read the flag somehow.
Trigger an event for form to capture. In it's handler read the flag status. If true, close/unload the form.
This page will tell you technical details and functions.
I don't think you need to make it modal... then you can take siride's option of closing it on the Deactivate event.
The reason you don't need to make it modal: The first time you display it, it will have the focus and be topmost. Modal prevents you from clicking somewhere else, but you want to be able to click somewhere else... and when you do, the form goes away, so there are no modal needs.

Display small form while main form is "locked"

i'm thinking about writing a WPF program that would require login and password at the app startup.
I thought about small form with two textboxes as a login form. User will have to fill in his details and then the main form of the application will be unlocked.
How will you solve this?
Thanks for your answers, daemonsvk
This is standard behavior for the Window.ShowDialog() call. Other windows will be disabled.
I would make the initial startup form your login page and authenticate the user, if their details are correct hide the login form and show you other form.
if(user is authed)
{
this.Hide(); //Hide the login form
mainAppForm.Show(); //or Form.ShowDialog(); //Shows the main form
}
The simplest way to do this is to first show (using ShowDialog, which blocks i.e. waits until the form is closed before continuing to the next line of code) the login form. If the login is successful, you dispose the login form and then show your main form; if the login fails, you end the application.
If, however, you want your main form to be visible underneath the login form (a not unreasonable requirement), then you need to first show the main form, and then display the login form (modally) from a method in the main form. In WinForms this requires some kind of hack, since you couldn't show the login form from either the main form's constructor or its Load event (as the main form won't yet be visible when the login form appears).
WPF may handle this better now.

What's the difference between Application.Run() and Form.ShowDialog()?

In my application I want to show a login form first and then the main form if the login has been successful. Currently I'm doing it something like this:
var A = new LoginForm();
if ( A.ShowDialog() == DialogResult.OK )
Application.Run(new MainForm());
But then I started wondering - what's the point of the Application.Run()? Why not just do (new MainForm()).ShowDialog() as well? What's the difference? And what would be the correct way to achieve what I want?
Application.Run(Form) starts a message loop on the current thread and displays the specified form. The message loop enables the form to receive Windows messages (eg, key presses, mouse clicks, paint invalidations) to allow it to appear responsive and have interaction with the user. When you call ShowDialog() on a Form instance, it actually does a similar thing and creates a modal message loop for the form on which ShowDialog has been called.
There is not much difference between the two calls. Application.Run does add some extra event handling enabling you to do some tidying up of resources when the main form is closed (see Application.ThreadExit).
The recommended way to start WinForms applications is using Application.Run, but I suspect this is more of a convention than a rule. The biggest reason to use Application.Run is if you want to open multiple non-modal forms. You can do this using:
new Form().Show();
new Form().Show();
Application.Run();
You could not achieve this using the ShowDialog() method as one of the forms would have to be modal.
As for your question of how to show a login form and then the main form if the login is successful, I think what you have is fine:
if (new LoginForm().ShowDialog() == DialogResult.OK)
{
Application.Run(new MainForm());
}
The alternative is to do the plumbing yourself and open an instance of MainForm in the closing event of the LoginForm if the login was successful.
From MSDN:
This method adds an event handler to
the mainForm parameter for the Closed
event. The event handler calls
ExitThread to clean up the
application.
http://msdn.microsoft.com/en-us/library/ms157902.aspx
From my testing, I noticed this main difference:
When Application.Run is used, the form's Close button (red X) returns DialogResult.None; however, when ShowDialog is used, the Close button produces DialogResult.Cancel.
Does this matter to you? In my code, I was testing for DialogResult.Cancel to determine the exit code of my application. That was broken when the red X was used to close the form. I now test for DialogResult.OK to indicate a successful exit.
return myForm.DialogResult == DialogResult.OK ? 0 : 1;
One key difference is that ShowDialog is usually a modal Dialog. If you wanted to create a user-friendly toolset, you would not want it to be comprised of modal dialog boxes.
Also, Application.Run() accepts more than just a form. It has a few overloads.
As for your application, I do not think it matters much. Application.Run makes sense to me because it denotes the start of your actual Application.
The documentation of the overload
public static void Run(
ApplicationContext context );
has a neat example with a different approach that involves two forms as well.
For a more concerete example of a difference:
If your main form is an MDI form, then the behavior on clicking the close button (the 'x' in the upper right, or Alt-F4) is different depending on which method you use to show the form.
With Application.Run(mainForm), the closing event of the child forms run, then the main form's closing event runs.
With mainForm.ShowDialog, the closing event of the main form runs, and the closing event of the child forms do not run.
Application.Run() is for the start of application while MainForm is part of the application and MainForm()).ShowDialog() used to display it only.
Application.Run() is the entry point for your Application. same as Main() method is for some class or ApplicationStart() for a WebApplication
Application.Run() has different overloads, one of which is without parameters. That Method starts application without an initial form.
From my testing I notice that using Application.Run buttons with DialogResult does not close the form (OnFormClosing is not hit) compare to ShowDialog in which the buttons with DialogResult hit OnFormClosing and the close the form.

Categories