如何制作单个实例表单(不是应用程序)?

RHa*_*uda 12 c# modal-dialog winforms

在我的C#应用​​程序中,我有一个可以从菜单命令打开的选项对话框.

我想确保选项对话框只有一个实例(用户不能在给定时间打开多个选项窗口)而不使其成为模态.

此外,如果用户已打开此窗口,并且他单击菜单项以再次打开它,则应用程序只会使已经可见的表单成为最顶层的窗口.

谁能指出我如何完成这些任务的方向?

非常感谢你.

Jon*_*eet 19

嗯,最简单的方法是有一个静态字段,用于存储对单个实例的引用或null,然后是一个检索它或创建一个新方法的方法.

请注意,这是不一样的使之成为单-因为我想如果形式是封闭的,你要创建一个新的实例下一次.(替代方案 - 隐藏它并重复使用 - 在STO的答案中显示.)你可能想要这样的东西:

public class OptionsDialog : Form
{
    private static OptionsDialog openForm = null;

    // No need for locking - you'll be doing all this on the UI thread...
    public static OptionsDialog GetInstance() 
    {
        if (openForm == null)
        {
            openForm = new OptionsDialog();
            openForm.FormClosed += delegate { openForm = null; };
        }
        return openForm;
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您可能希望使该方法执行"将其置于最前面"的步骤.

  • 我很困惑为什么 Microsoft 不在 .Net Framework 中提供一些简单的方法来让开发人员有机会轻松指定“在任何时间仅打开此表单的一个实例”。奇怪。 (2认同)

Han*_*ant 10

您需要阻止表单关闭.如果不这样做,表格将被处理并变得无法使用.您可以通过实现FormClosing事件来执行此操作:

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (e.CloseReason == CloseReason.UserClosing) {
            this.Hide();
            e.Cancel = true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

要使它成为单例,只需跟踪主表单类中表单的生命周期:

    frmOptions options;

    private void btnShowOptions_Click(object sender, EventArgs e) {
        if (options == null) {
            options = new frmOptions();
            // To make absolutely sure:
            options.FormClosed += (o, ea) => options = null;
        }
        else {
            options.WindowState = FormWindowState.Normal;
        }
        options.Show();
    }
Run Code Online (Sandbox Code Playgroud)

  • 这是一个lambda表达式.我通常写(发件人,e)=>但这些名字已经在使用中. (2认同)

vol*_*ody 7

您需要此表格作为财产

Form1 myForm = null;
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    myForm = null;
}

private void ShowForm()
{
    if (myForm != null)
    {
        myForm.BringToFront();
    }
    else
    {
        myForm = new Form1;
        myForm.Show();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 只需将 myForm 声明为静态,以便我的选项表单 FormClosed 事件可以访问(再次使 myForm = null)。 (2认同)