C# dialogresult wont close form - c#

I am developing an application which requires loggging in.
I've developed the following forms:
- frmMain
- frmLogon
Form main launches when bootstrapping the windows forms application. In the "Shown" event of form main the FrmLogon form is shown as a dialog.
However when automatically setting the DialogResult to OK the form won't close, the program only works when manually hitting the "Logon" button, which triggers the exact same functionality.
Ive tried to Close() the form logon, but this leaves me with an System.ObjectDisposedException.
Any suggestions?
FrmMain.CS
private void OnFormShown(object sender, EventArgs e)
{
OnClickMenuLogon(sender, e);
}
private void OnClickMenuLogon(object sender, EventArgs e)
{
if (IsLoggedOn())
{
G.LogOff();
User = null;
OnLoggedOff();
}
else
{
FrmLogon logon = new FrmLogon(G, true);
DialogResult result = logon.ShowDialog();
if (result == DialogResult.OK)
{
User = logon.User;
_hostName = User.Name + " # " + (String.IsNullOrEmpty(logon.HostName) ? Environment.MachineName : logon.HostName);
OnLoggedOn();
}
}
}
FrmLogon.CS
private void OnLogOnSuccess(object sender, LoggedOnEventArgs e)
{
tbStatus.Text = $"[{DateTime.Now.ToString("HH:mm:ss")}]: Successfully logged on.\r\n" + tbStatus.Text;
User = _g.LoggedUser;
HostName = tbHost.Text;
DialogResult = DialogResult.OK;
}
Edit: When using
this.DialogResult = DialogResult.OK;
this.Close();
the following exception occurs:
Exception screenshot

Instead of just using
DialogResult = DialogResult.OK;
Use
this.DialogResult = DialogResult.OK;
this.Close();
this.Close() will close your second form and return it's current DialogResult.
UPDATE 1
Other way is to add some invisible button to the Dialog Form, set it as AcceptButton and perform click on it in this way:
Button bt = new Button();
bt.Click += new EventHandler((sender1,e1)=> {
this.DialogResult = DialogResult.OK;
});
bt.FlatStyle = FlatStyle.Flat;
bt.FlatAppearance.BorderColor = BackColor;
bt.FlatAppearance.MouseOverBackColor = BackColor;
bt.FlatAppearance.MouseDownBackColor = BackColor;
this.Controls.Add(bt);
this.AcceptButton = bt;
bt.PerformClick();

Problem is solved, the attempt to logon was made in the FrmLogon's constructor which caused the DialogResult to be set before the form was initialized. After implementing the "Shown" event and calling the functionality from there in FrmLogon the problem was solved. Thank you all.

Related

How to separate custom Close Button from Window_Closing?

I'm building the WPF app with multiple forms, and my goal is that, on, let's say LoginForm I have a button called Login, which, when clicked, closes current form (LoginForm from above) and opens another form (let's say Form1).
Note that I'm trying to have only one form opened at a time.
Code -
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
if(everything okay)
{
Form1 frm = new Form1();
frm.Show();
Close();
}
else
{
return;
}
}
This works fine. But, my second idea is that, if X in the top right corner is clicked, I want to close this form, and not to open any other, basically exiting the app.
Code-
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
MessageBoxResult rez = MessageBox.Show("Do you wish to leave the app?", "Question?", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (rez != MessageBoxResult.Yes)
{
e.Cancel = true;
}
}
This is where my problem starts, I've found that Window_Closing and this.Close() are same event, so, when I click the Login button, MessageBoxResult still shows up, even tho that is not my goal. I want to somehow separate those two events, if that is possible. How can I do so?
You could temporarily unhook the event handler just before you call Close():
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
if (everything okay)
{
Form1 frm = new Form1();
frm.Show();
Closing -= Window_Closing;
Close();
Closing += Window_Closing;
}
else
{
return;
}
}
Or use a bool variable to determine whether to display the MessageBox:
private bool _showMessageBox = true;
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
if (everything okay)
{
Form1 frm = new Form1();
frm.Show();
_showMessageBox = false;
Close();
_showMessageBox = true;
}
else
{
return;
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!_showMessageBox)
return;
MessageBoxResult rez = MessageBox.Show("Do you wish to leave the app?", "Question?", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (rez != MessageBoxResult.Yes)
{
e.Cancel = true;
}
}
this.Close is not a event. this.Close() is a method and after that the event Window_Closing is raised
Try something like that:
Form1 frm = new Form1();
Hide();
frm.ShowDialog();
Close();
you create a form, then you hide the login form and then you show the Dialog of the form. The Close will then be raised after the new Form1() is closed.

Call event on first form when second form closes

I have two forms, I open and showdialog the second form like this:
Recieving_Stock_Form f = new Recieving_Stock_Form();
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
f.ShowDialog();
Now when I close the second form I want to trigger an event on the first form
E.G
void txtStockCount_TextChanged(object sender, EventArgs e)
Any ideas where I can look up about this or how to do it?
Thanks
in Form1, assuming that your code is this
Recieving_Stock_Form f = new Recieving_Stock_Form();
You can add the code
f.Form_Closing += ExampleHandler;
ExampleHandler(object sender, FormClosingEventArgs e)
{
//Do stuff
}
I'd rather not had cheated with the form; instead, I suggest assigning the value from Recieving_Stock_Form to txtStockCount:
using (Recieving_Stock_Form f = new Recieving_Stock_Form()) {
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
// == DialogResult.OK - let user have a chance to cancel his/her input
if (f.ShowDialog() == DialogResult.OK) {
//TODO: put the right property here
txtStockCount.Text = f.StockCount.ToString();
}
}
The ShowDialog is modal so it will block executiong, so when you close it, the next thing is executed.
You can do this:
Recieving_Stock_Form f = new Recieving_Stock_Form();
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
f.ShowDialog();
// it will continue here when the form is closed.
txtStockCount_TextChanged(this, EventArgs.Empty); // or assign the variable directly.
There is two events that you can handle - FormClosed and FormClosing, depending on your decision.
f.FormClosed += f_FormClosed;
private void f_FormClosed(object sender, FormClosedEventArgs e)
{
//Call your function or do whatever you want
}

how to exit from application on click of (red X ) button right top on winform

i have two forms in my application. frmLogin and frmDash. after login. i am hiding frmLogin on click of login button. ad showing frmDash.
in frmDash, there is LogOut button. on click of LogOut, i am using this.Close() and showing login form. but now if i click (red X) button of frmLogin whole application is not terminating. plz give some suggestions.
i have tried this.:
private void btnLogin_Click(object sender, EventArgs e)
{
try
{
this.Hide();
string Log_API = "http://api.retailbutton.co/WS/Service.php?Service=employeeLogin";
if (LoginUser(Log_API))
{
logIn_Status = "true";
GlolbalUtil.LogIn_Status = logIn_Status;
frmDash frmDash = new frmDash();
frmDash.Owner = this;
frmDash.Show();
txtUsername.Text = "";
txtPassword.Text = "";
//GlolbalUtil.accept_status = "1";
}
else
{
MessageBox.Show("Please Check Username and password");
FrmLogin frmLogin = new FrmLogin();
frmLogin.Owner = this;
frmLogin.Show();
}
}
code for Logout button of frmDash:
private void button1_Click(object sender, EventArgs e)
{
GlolbalUtil.LogIn_Status = "false";
this.Close();
FrmLogin fl = new FrmLogin();
fl.Show();
}
You create a new instance of frmDash when you log in and hide the form.
Then when you are logging out, you say this.close() and create another new instance of FrmLogin. Not going back to the original instance of FrmLogin.
This means that you will always will have the hidden instance which you started with.
(If you close the new instance of FrmLogin, the hidden FrmLogin still exists.)
You can add the following in btnLogin_Click:
frmDash.ParentForm = this;
and button1_Click should look like this:
private void button1_Click(object sender, EventArgs e){
GlolbalUtil.LogIn_Status = "false";
FrmLogin fl = (FrmLogin)this.Parent; //Prior it said ParentForm
this.Close();
fl.Show();
}
If you implement this, you will show the initial login form and when you close it, you close the initial instance of the login form.
#Edit 10:52 25-06-2015
ParentForm cannot be assigned and is read only. A solution is to assign it to Parent or the following can also be applied in btnLogin_Click:
frmDash.Owner = this;
and button1_Click:
private void button1_Click(object sender, EventArgs e){
GlolbalUtil.LogIn_Status = "false";
FrmLogin fl = (FrmLogin)this.Owner
this.Close();
fl.Show();
}
#Edit 08:16 29-06-2015 (Next question)
private void btnLogin_Click(object sender, EventArgs e)
{
try
{
string Log_API = "http://api.retailbutton.co/WS/Service.php?Service=employeeLogin";
if (LoginUser(Log_API))
{
logIn_Status = "true";
GlolbalUtil.LogIn_Status = logIn_Status;
frmDash frmDash = new frmDash();
frmDash.Owner = this;
////If you hide here, you do not have to make
//a new instance when the if statement is not true.////
this.Hide();
frmDash.Show();
txtUsername.Text = "";
txtPassword.Text = "";
//GlolbalUtil.accept_status = "1";
}
else
{
MessageBox.Show("Please Check Username and password");
////Delete following////
//FrmLogin frmLogin = new FrmLogin();
//frmLogin.Owner = this;
//frmLogin.Show();
}
}
If you are using a custom button, do this
private void QuitButton_Click(object sender, EventArgs e)
{
DialogResult DialogResult = MessageBox.Show("Do you really want to exit?", "Confirmation",
MessageBoxButtons.YesNo, MessageBoxIcon.Hand);
if (DialogResult == DialogResult.Yes)
Application.Exit();//Here is the code to close everything
else
//Do stuff
}
If you are using the X button, add a FormClosing Event and the code look like this:
private void Form1_FormClosing(object sender, FormClosingEventArgs e){
DialogResult DialogResult = MessageBox.Show("Do you really want to exit?", "Confirmation",
MessageBoxButtons.YesNo, MessageBoxIcon.Hand);
if (DialogResult == DialogResult.Yes)
Application.Exit();//Here is the code to close everything
else
//Do stuff
}
use Application.Exit(); method when your button clicked
Add this to your Designer.cs
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.SampleClassName_FormClosed);
then right click the SampleClassName_FormClosed and click "Go to Definition".
then inside the created class call the form that you want to close.
Try the following on your 2. Form:
public partial class Form2 : Form
{
private bool ForceClose = true;
public Form2()
{
InitializeComponent();
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
if (ForceClose)
Application.Exit();
}
private void button1_Click(object sender, EventArgs e)
{
GlolbalUtil.LogIn_Status = "false";
ForceClose = false;
this.Close();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Application.Exit();//close the whole program using x (red)button
}

Form Closes When it Shouldn't

I have two Forms in my application. They way I call Form 2 is like this:
Form 1:
private void btnTest_Click(object sender, EventArgs e)
{
DialogResult result = new System.Windows.Forms.DialogResult();
Add_Link addLink = new Add_Link();
result=addLink.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
//
}
}
Form 2:
private void btnAdd_Click(object sender, EventArgs e)
{
if(validURL(txtSubLink.Text))
{
HyperLink add = new HyperLink(txtSubLink.Text,txtSubText.Text,"URL");
this.build = add;
}
else
{
MessageBox.Show("Valid URL Needed! " + txtSubLink.Text, "ERROR");
}
}
My problem is if the user clicks the Add button, the error message shows(because the data is invalid or the textboxes are empty) BUT it closes the form. I only want the user to close the form and pass the data back if the two textboxes contain the proper data. If the two textboxes don't contain the proper data OR is empty, when the user clicks Add, the error message should show, and the Form 2 should remain open, How do I get that to happen...?
I suspect your btnAdd has its DialogResult property set to OK. Unset that, and then add this.DialogResult = DialogResult.OK in your event handler when you're satisfied with the input.
private void btnAdd_Click(object sender, EventArgs e)
{
if(validURL(txtSubLink.Text))
{
HyperLink add = new HyperLink(txtSubLink.Text,txtSubText.Text,"URL");
this.build = add;
this.DialogResult = DialogResult.OK;
}
else
{
MessageBox.Show("Valid URL Needed! " + txtSubLink.Text, "ERROR");
}
}

An Event Handler when Close Button is clicked in windows form

I was wondering if there are any event handlers if the user clicked the close button in a windows form. My initial plan was when the user clicked the close button, it will return a boolean to the caller or whoever called that form. for example
public void newWindow(){
NewForm nw = new NewForm();
nw.ShowDialog();
if(nw.isClosed){
do something
}
}
is that possible?
If you are using .ShowDialog(), you can obtain a result via the DialogResult property.
public void newWindow()
{
Form1 nw = new Form1();
DialogResult result = nw.ShowDialog();
//do something after the dialog closed...
}
Then in your click event handlers on Form1:
private void buttonOk_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
private void buttonCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
If you do not want to open the new form as a dialog, you can do this:
public void newWindow()
{
Form2 nw = new Form2();
nw.FormClosed += nw_FormClosed;
nw.Show();
}
void nw_FormClosed(object sender, FormClosedEventArgs e)
{
var form = sender as Form2;
form.FormClosed -= nw_FormClosed; //unhook the event handler
//you can still retrieve the DialogResult if you want it...
DialogResult result = form.DialogResult;
//do something
}
You should take a look at the FormClosing Event or since you are using ShowDialog you can do something like this. You can also change the DialogResult that is returned in the FormClosing Event.
DialogResult dr = nw.ShowDialog();
if (dr == DialogResult.Cancel)
{
//Do Stuff
}
You're almost there!
You don't need the if(nw.isClosed), the line do something will only get executed when nw will be closed
If you need to 'return' a value from that dialog, know this: The dialog is not immediatly released when you close it. So you can do something like this:
NewForm nw = new NewForm();
nw.ShowDialog();
var x = nw.Property1

Categories

Resources