I am writing a WinForm application in C#. There is a Form A
that opens Form C
on Button
click. Now, I want to add a password input screen Form B
before opening Form C
. Only if the password entered is correct will Form C
open, and otherwise, show an error message. Form B
just has a TextBox
control and a Verify Button
control.
/*Form A*/
FormB fb;
private void BtnClick(object sender, EventArgs e) {
DialogResult result;
//fb can open once at a time
if(fb == null){
fb = new FormB();
fb.FormClosed += new FormClosedEventHandler(FormB_FormClosed);
//This seems to be not working
result = fb.ShowDialog();
}
else //FormB already open. Do nothing
return;
//Only if password entered is correct, proceed
if(result == DialogResult.Yes){ //result == cancel
//Code to open Form C //Program never reaches here
}
}
//Upon closing FormB, reset it to null
private void FormB_FormClosed(object sender, FormClosedEventArgs e){
if(fb != null)
fb = null;
}
/* Form B */
private const string password = "xxxyyyzzz";
private void BtnPW_Click(object sender, EventArgs e){
bool result = Verify();
if(result){
BtnPW.DialogResult = DialogResult.Yes;
}
else{
MessageBox.Show("Error: Incorrect password");
BtnPW.DialogResult = DialogResult.No;
}
this.Close(); //Added
}
private bool Verify(){
if(TxtBox.Text == password)
return true;
else
return false;
}
Can someone tell me what is wrong with this code? It never reaches the second if
statement in Form A
.
Edit: Even if I enter the correct password and hit the button on Form B
, result
in Form A
gets "DialogResult.Cancel`.
If you call the Form.Close method, then the DialogResult property of that form is set to DialogResult.Cancel even if you have set it to something else. To HIDE a form opened modally you just need to set the form's DialogResult property to anything but DialogResult.None.
Said that your code seems to be not the one usually used to handle a modal dialog.
ShowDialog is blocking your code, you don't exit from this call until the called form is closed or hidden, so you don't need to keep a global variable of FormB around and handle the FormClosed event handler of FormB in FormA.
private void BtnClick(object sender, EventArgs e)
{
using(FormB fb = new FormB())
{
// Here the code returns only when the fb instance is hidden
result = fb.ShowDialog();
if(result == DialogResult.Yes)
{
//open Form C
}
}
}
Now you should remove the call to Form.Close in the FormB code and set directly the DialogResult property of the FormB, do not try to change at this point the DialogResult property of the buttons, this will not work and you need a second click to hide the form, instead set directly the form's DialogResult property.
private const string password = "xxxyyyzzz";
private void BtnPW_Click(object sender, EventArgs e)
{
if(Verify())
this.DialogResult = DialogResult.Yes;
else
{
MessageBox.Show("Error: Incorrect password");
this.DialogResult = DialogResult.No;
}
}
In this way the form is hidden (not closed) and your code exits from the ShowDialog call in the FormA. Inside the using block you can still use the FormB instance to read its properties and take the appropriate paths. When your code exits from the using block the fb instance will be automatically closed and disposed out of existence.