33

在回答我最近遇到的一个问题(Here)时,Hans Passant 说我应该设置DialogResult关闭我的表格,而不是form.Close()虽然我似乎无法找出原因?

如果我没看错的话,MSDN 文档指出这样做只会隐藏表单,而不是像我认为.Close()的那样正确处理它?

从文档中提取。

当用户单击对话框的关闭按钮或设置 DialogResult 属性的值时,不会自动调用 Close 方法。相反,该表单被隐藏并且可以在不创建对话框的新实例的情况下再次显示。由于这种行为,当您的应用程序不再需要该表单时,您必须调用该表单的 Dispose 方法。

另一方面,微软创建了一个支持页面,说明如何使用 DialogResult 属性,并在“验证它的工作原理”部分中指出,单击将关闭表单。

所以我的问题有两个,我应该继续使用 Close 还是 DialogResult ;并且对话框结果是否关闭或隐藏表单。从我在下面制作的代码(一个带有两个按钮的简单表单)中,看起来它确实是隐藏的,只有当一个断点this.Close()被击中时..(有this.Close()评论,表单仍然消失,只是不确定是否隐藏)

    public Form1()
    {
        InitializeComponent();
        button1.Click += (s, e) =>
            {
                 //I edited my question to include using
                using(Form1 form = new Form1())
                {
                    form.ShowDialog();
                }

            };
        button2.Click += (s, e) => 
            {
                this.DialogResult = DialogResult.OK;
                this.Close();
            };
    }
4

2 回答 2

26

当您使用 ShowDialog 打开模式对话框时,调用代码将被阻止,直到调用的窗体关闭或隐藏。如果你想读取被调用表单的一些公共属性并且想要基于点击 OK 或 Cancel 按钮来做一些事情(例如将数据保存到数据库或文件中),那么你需要知道用户是否想要做或不做动作。ShowDialog() 方法返回的 DialogResult 允许您采取适当的操作...

所以例如

using (Form1 form = new Form1())
{
    DialogResult dr = form.ShowDialog();
    if(dr == DialogResult.OK)
    {
        string custName = form.CustomerName;
        SaveToFile(custName);
    }
    
}

要添加到此答案中的重要一点是,该DialogResult属性同时存在于 Form 类和 Button 类中。将按钮的 DialogResult 属性(通过代码或设计器)设置为不同于的值DialogResult.None是激活表单重要行为的关键。如果您单击设置了该属性的按钮,则表单引擎会将 Buttons 属性的值传输到 Forms 并触发表单的自动关闭,从而重新激活调用者代码。如果您在按钮单击上有一个事件处理程序,那么您可以运行代码来验证表单的输入并强制表单保持打开状态,覆盖表单的 DialogResult 属性,将其设置回 DialogResult.None

例如,在模态显示的表单中,您可以拥有:

// Event handler for the OK button set with DialogResult.OK
public void cmdOK_Click(object sender, EventArgs e)
{
     // Your code that checks the form data and
     // eventually display an error message.
     bool isFormDataValid = ValidateFormData();

     // If data is not valid force the form to stay open
     if(!isFormDataValid)
        this.DialogResult = DialogResult.None;
}
于 2013-05-30T22:14:02.567 回答
5

是否调用Close或设置DialogResult属性并不是真正的问题。您只需要确保调用Dispose. 我更喜欢使用 using 块来执行此操作:

using (Form1 form = new Form1())
{
    form.ShowDialog();
}

我原本以为你可以调用ShowDialog一个Form已经调用了它的Close方法。不是这种情况。如果您使用 以模态方式显示表单ShowDialog,则它是否由于该Close方法或设置DialogResult属性而关闭似乎并不重要。似乎设置DialogResult只是关闭Form.

但是无论您调用Close还是设置DialogResult属性,关键是确保您调用Dispose()或将表单放入 using 块中。

于 2013-05-30T22:05:35.643 回答