在回答最近的一个问题,我有(这里),汉斯Passant说,我应该设置DialogResult
关闭我的形式,而不是form.Close()
,虽然我似乎找不到为什么?
如果我读得正确,MSDN文档指出,这样做只会隐藏表单,而不是正确处置它,我相信.Close()
做?
从文档中提取
当用户单击对话框的Close按钮或设置dialgresult属性的值时,不会自动调用Close方法。相反,表单是隐藏的,无需创建对话框的新实例即可再次显示。由于这种行为,当应用程序不再需要窗体时,必须调用窗体的Dispose方法。
另一方面,微软已经创建了一个支持页面,说明如何使用dialgresult属性,并在"验证它的工作"部分声明,点击这样将关闭窗体。
所以我的问题是双重的,我应该继续使用Close或dialgresult代替;对话框结果是否关闭或隐藏窗体。从我下面做的代码(一个简单的形式与两个按钮),似乎它确实是隐藏的,只有在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();
};
}
当你用ShowDialog打开一个模态对话框时,调用代码会被阻塞,直到被调用的窗体关闭或隐藏。如果您希望读取被调用表单的一些公共属性,并希望根据单击OK或Cancel按钮执行操作(例如将数据保存到数据库或文件),那么您需要知道用户是否希望执行该操作。ShowDialog()方法返回的dialgresult允许您采取适当的操作…
例如
using (Form1 form = new Form1())
{
DialogResult dr = form.ShowDialog();
if(dr == DialogResult.OK)
{
string custName = form.CustomerName;
SaveToFile(custName);
}
}
要添加到这个答案的一个重要的事情是DialogResult
属性同时存在于Form类和Button类中。将按钮的dialgresult属性(通过代码或设计器)设置为不同于DialogResult.None
的值是激活表单重要行为的关键。如果单击设置了该属性的按钮,则Forms Engine将Buttons属性的值传输到Forms属性,并触发表单的自动关闭,重新激活调用方代码。如果你在按钮点击上有一个事件处理程序,那么你可以运行代码来验证表单的输入,并强制表单保持打开状态,覆盖表单的dialgresult属性,将其设置回dialgresult。没有一个
例如,在模态显示形式中,您可以使用:
// 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;
}
是否调用Close
或设置DialogResult
属性并不是真正的问题。你只需要确保调用Dispose
。我更喜欢用using语句块:
using (Form1 form = new Form1())
{
form.ShowDialog();
}
我最初认为你可以在已经调用了Close
方法的Form
上调用ShowDialog
。事实并非如此。如果您使用ShowDialog
模态显示表单,则由于Close
方法或设置DialogResult
属性是否关闭似乎并不重要。似乎设置DialogResult
只是关闭Form
的捷径。
但是无论你是调用Close
还是设置DialogResult
属性,关键是要确保你调用Dispose()
或者把你的表单放在using块中