C# AcceptButton和验证

24

你好,我有一个包含多个文本框和两个按钮“取消”和“确定”的表单。这些按钮被分配为表单中的接受和取消按钮属性。问题是我必须验证所有文本框中输入的文本。

如果用户点击“确定”按钮(即acceptButton),我希望能够进行验证。因此,我编写了一个负责验证的函数,并且在用户单击“确定”按钮时调用该函数。但是,即使验证函数返回false,我也无法阻止表单关闭。这是因为我将acceptbutton属性分配给了我的“确定”按钮。有没有办法在不删除acceptbutton属性的情况下,防止表单在验证失败时关闭?

5个回答

36

这是我们使用的可行解决方案(有些内容是从其他回答中编译而来)。

你只需将 DialogResult 设置为 None 就可以防止窗体关闭。

//form init, auto-generated code (this is the case described)
private void InitializeComponent()
{
    //....
    this.AcceptButton = btnOk;
    this.btnOk.DialogResult = DialogResult.OK;
    //....
}

//event handlers
private void btnOK_Click(object sender, EventArgs e)
{
    if (!Validate())
        this.DialogResult = DialogResult.None;
}

private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.DialogResult == DialogResult.None)
        e.Cancel = true;
}

8
需要添加FormClosing事件处理程序吗?对我而言,将DialogResult设置为None就足够了。 - NobodysNightmare

8
在“确定”按钮的点击处理程序中,当验证失败时将 DialogResult 更改为 DialogResult.None

不起作用 :( 尽管我按照您说的设置了DialorResult,但表单仍在关闭 - exMode
1
对我来说可以。也许 exMode 不小心将其设置为 DialogResult.No,而不是 DialogResult.None? - Jeff Roe

7

一种可能的方法是在OnFormClosing事件中应用验证,并根据验证结果取消操作。

--编辑--

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.DialogResult == DialogResult.OK)
    {
        if (!IsValid())
        {
            Info("Invalid data");
            e.Cancel = true;
        }
        else
        {
            Info("Valid data found, closing dialog");
        }
    }
    else if (this.DialogResult == DialogResult.Cancel)
    {
        Info("Just cancelling!");
    }
}

当你在取消/确定事件上调用this.Close();

或者,在您的确认按钮实现中,您可以更改按钮的DialogResult并将其设置为None

acceptButton.DialogResult = DialogResult.None;

第一个代码片段可以正常工作,但是它阻止了关闭操作,即使您点击了取消按钮。 - exMode
@exMode:根据您的评论,看看我的更新代码。Info()只是调用MessageBox的方法。 - KMån
但是在窗体关闭事件上侦听意味着您设置了DialogResult值,让对话框发布一个事件分派,然后它被取消,然后窗体的DialogResult被改回为none。为什么要额外监听Form.Close?只需等待并在验证时设置DialogResult的值,而不是每次都设置。 - Patrick
@Patrick:这并不意味着你设置了对话框结果的值。当你按下取消按钮时,框架会为你执行此操作,它会为你更改DialogResult的状态。试试看。 - KMån
但这仍然意味着表单上的DialogResult设置为按钮的DialogResult,即使您没有明确地设置它,这会导致一些不必要的额外调用。另外,顺便提一下,如果您在按钮上设置了DialogResult,则无需在表单上调用this.Close() - Patrick

1
不要在设计器或其他地方设置Button.DialogResult(不要与Form.DialogResult混淆)。在Button的单击处理程序中进行验证,如果成功,则将Form.DialogResult设置为DialogResult.OK并关闭窗体。
private void OkBtn_Click(object sender, EventArgs e)
{
    if (isValid())
    { 
      this.DialogResult = DialogResult.OK;
      this.Close();
    }
}

1

不要在表单中设置AcceptButton属性,并从按钮中删除DialogResult属性(将其设置为DialogResult.None)。

您可以在验证代码中设置窗体的DialogResult属性。

 if (allFieldsValidated) {
     DialogResult = DialogResult.OK;
 }

我之前尝试过这种方法,但是这段代码不起作用。如果我点击“确定”按钮并且验证返回true,什么也不会发生,但是如果我再次点击“确定”按钮,表单就会关闭。 - exMode
@exMode:你说什么都不发生是什么意思?它不进行验证吗?当您完成验证后,无法将表单的“DialogResult”设置为“DialogResult.OK”并使表单自行关闭吗? - Patrick
我的意思是,即使验证返回true,表单也不会关闭。不幸的是,我无法放弃设置DialorResult.OK。 - exMode
你需要添加一个 Close(); 方法来关闭窗体。 - John Hartley
@JohnHartley:从什么时候开始的? - Patrick
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接