关闭模式窗体,当我释放用户控件时,该窗体由用户控件的按钮打开



我有一个应用程序,我需要确保通过使用ShowDialog()单击用户控件上的按钮打开的表单将在我处置用户控件时关闭并释放。

我通过计时器以我的主形式调用userControl.Dispose()

有没有办法做到这一点?

谢谢。。。

以下是有关表单流程的更多详细信息:

我的应用程序MainForm是创建一个具有ButtonUserControl。比当用户单击用户控件的按钮时,它显示使用ShowDialog的模型窗体。

同时,几分钟后,主窗体中的计时器将现有用户控件替换为用户控件的另一个实例。主窗体调用上一个用户控件的Dispose方法,并显示新的 on。

但问题是模态对话框仍然在屏幕上打开,阻塞了主窗体。我想关闭它,并且不应执行放置在ShowDialog方法之后的代码。

简答

您可以订阅DisposedUserControl事件并关闭它显示的表单。关于问题下的评论,看起来您有一个包含ButtonUserControl,如果按钮Click,您可以使用ShowDialog()显示Form

若要关闭和处置表单,您需要先订阅DisposedUserControl的事件,然后再将表单显示为对话框。

更多详情

如果要根据窗体的对话框结果决定运行某些逻辑,可以检查对话框结果,如果正常,则运行所需的自定义逻辑。

若要稍微增强流,可以在用户控件中定义一些事件和属性,并在主窗体中处理它们:

  • OKSelected事件,如果对话框结果正常,则可以在关闭对话框后立即引发它。它将允许您在主窗体中处理此事件,例如,如果用户在对话框中单击"确定",则停止计时器。
  • ProcessingFinished,当对话框结果正常时,您可以在关闭对话框后完成一些处理后提出它。您可以在主窗体中处理此问题,例如再次启动计时器。
  • 您可以定义一些属性,以防您想要与主窗体传达某些值。

下面是主窗体中的代码示例:

MyUserControl uc = null;
private void timer1_Tick(object sender, EventArgs e)
{
if (!(uc == null || uc.IsDisposed || uc.Disposing))
{
this.Controls.Remove(uc);
uc.Dispose();
}
uc = new MyUserControl();
this.Controls.Add(uc);
uc.OKSelected += (obj, args) => { timer1.Stop(); };
uc.ProcessingFinished += (obj, args) =>
{
MessageBox.Show(uc.Info);
timer1.Start();
};
}

下面是用户控件的示例:

public partial class MyUserControl : UserControl
{
public MyUserControl() { InitializeComponent(); }
public EventHandler OKSelected;
public EventHandler ProcessingFinished;
public string Info { get; private set; }
private void button1_Click(object sender, EventArgs e)
{
using (var f = new Form()) {
var button = new Button() { Text = "OK" };
f.Controls.Add(button);
button.DialogResult = DialogResult.OK;
this.Disposed += (obj, args) => {
if (!(f.IsDisposed || f.Disposing)) {
f.Close(); f.Dispose();
}
};
if (f.ShowDialog() == DialogResult.OK) {
//If you need, raise the OKSelected event
//So you can handle it in the main form, for example to stop timer
OKSelected?.Invoke(this, EventArgs.Empty);
//
//Do whatever you need to do after user closed the dialog by OK
//
//If you need, raise the ProcessingFinished event
//So you can handle it in the main form, for example to start timer
//You can also set some properties to share information with main form
Info = "something";
ProcessingFinished?.Invoke(this, EventArgs.Empty);
}
}
}
}

您可以修改要自动关闭的表单吗?如果是这样,请尝试向每个表单添加以下内容:

protected override void OnShown(EventArgs e)
{
base.OnShown(e);
if (this.Owner != null)
this.Owner.HandleDestroyed += onOwnerHandleDestroyed;
}
void onOwnerHandleDestroyed(object sender, EventArgs e)
{
this.Close();
}

注意:您已经在使用Dispose()关闭主窗体,因此这应该可以工作。但是,如果您使用Close()关闭主窗体,则它不起作用,因为如果窗体是任何模式对话框的父项Close()则不会关闭窗体。

最新更新