【问题标题】:Receiving password input using DialogShow() not working使用 DialogShow() 接收密码输入不起作用
【发布时间】:2018-04-26 12:16:08
【问题描述】:

我正在用 C# 编写一个 WinForm 应用程序。有一个Form AButton 点击时打开Form C。现在,我想在打开Form C 之前添加一个密码输入屏幕Form B。只有输入的密码正确才会打开Form C,否则会显示错误消息。 Form B 只有一个 TextBox 控件和一个 Verify Button 控件。

/*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;
}

谁能告诉我这段代码有什么问题?它永远不会到达Form A 中的第二个if 语句。

编辑:即使我输入了正确的密码并点击了Form B 上的按钮,Form A 中的result 也会得到“DialogResult.Cancel`”。

【问题讨论】:

  • “这似乎不起作用” -- 这不是一个非常有用的评论。当它到达那条线时,您希望看到什么,而您又看到了什么?您是否在 BtnClick 的顶部放置了一个断点,并确认它确实被调用了,并且您确实在通过代码遵循您期望的路径?
  • 我很抱歉。我跳过了一些句子,所以我只是纠正了我的问题。即使在Form B 中输入了正确的密码,我的代码也永远不会打开Form C
  • 你错过了 btnPW.DialogResult 的要点。这说明如果用户单击该按钮将返回什么结果。它没有说明返回什么结果
  • 首先,它打开Form B,我输入密码(不正确或正确)并点击Verify按钮,触发BtnPW_Click方法。到达 this.Close() 后,它离开了该方法,但result = fb.ShowDialog();cancel 作为result 的值。
  • 你最好在表单b中设置一个字段并在showdialog之后查询它。即有public bool PasswordOK;

标签: c# winforms dialogresult


【解决方案1】:

如果您调用 Form.Close 方法,则该表单的 DialogResult 属性将设置为 DialogResult.Cancel,即使您已将其设置为其他值。要隐藏以模态方式打开的表单,您只需将表单的 DialogResult 属性设置为 DialogResult.None 以外的任何值。

说您的代码似乎不是通常用于处理模态对话框的代码。
ShowDialog 阻塞了你的代码,直到被调用的表单关闭或隐藏后你才退出这个调用,所以你不需要在 FormA 中保留 FormB 的全局变量并处理 FormB 的 FormClosed 事件处理程序。

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          
        }    
   }     
}

现在你应该去掉 FormB 代码中对 Form.Close 的调用,直接设置 FormB 的 DialogResult 属性,此时不要试图改变按钮的 DialogResult 属性,这不起作用,你需要一个第二次点击隐藏表单,而是直接设置表单的DialogResult属性。

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;
     }
}

通过这种方式,表单被隐藏(未关闭),并且您的代码从 FormA 中的 ShowDialog 调用中退出。在 using 块中,您仍然可以使用 FormB 实例来读取其属性并采用适当的路径。当您的代码从 using 块中退出时,fb 实例将自动关闭并不再存在。

【讨论】:

  • 谢谢,但即使在单击 BtnPW 后,Form B 也不会关闭。此外,添加 Close() 不会关闭表单。单击 BtnPW 两次后它会关闭表单...
  • 哎呀,我有BtnPW.DialogResult = DialogResult.No/Yes,这是导致问题的原因。谢谢!我一改成this.DialogResult = DialogResult.No/Yes,它就开始工作了
  • 如上所述,您不应更改按钮单击事件内的按钮的 DialogResult 属性。您无法保证表单引擎在您的代码从事件处理程序退出后读取 DialogResult 属性。实际上,它会在调用事件处理程序之前读取该属性,并且根据您的经验,您需要再次单击以关闭该表单。在这种情况下,直接设置表单的 DialogResult 属性是正确的方法。
猜你喜欢
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 2014-02-28
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
相关资源
最近更新 更多