WinForm表单的新实例

时间:2011-12-13 04:26:06

标签: c# .net winforms

我有这段代码:

Form1 newForm = new Form1();
newForm.Show(); 

//The rest of this code has been omitted

或多或少。 Form1仅用于示例目的。我的问题是我正在创建一个文本编辑器(基本上是我的上一个问题的延续),我希望能够同时打开多个Form1的副本。

这段代码允许我这样做,这很棒,但我希望能够关闭旧的,并且仍然在屏幕上显示newForm。目前,如果我关闭Form1,我会告别newForm。

这可能吗?我不想只是像记事本一样把所有的东西都白掉了。

4 个答案:

答案 0 :(得分:4)

我猜你的Form1也是您Application.Run()方法中创建并传递给main的那个,对吗?像Application.Run(new Form1());

这样的东西

在这种情况下(这是默认值),您告诉框架在该表单关闭时退出应用程序。

您可能希望更改main方法以使用overload of Application.Run() that takes an ApplicationContext,并在应用程序上下文中创建表单 - 然后当您的上一个表单关闭时,您可以退出该应用程序。 MSDN链接中的示例显示了一个非常类似的情况。

您只需将main更改为:

Form1 newForm = new Form1();
newForm.Show();
Application.Run();

但问题是,如果没有更多的内务管理,应用程序可能无法正确退出。

<强>加了: 这是一个简单的例子,但显示了这个概念。像这样创建一个ApplicationContext类:

public class CustomContext : ApplicationContext
{
    private readonly List<Form1> _openForms = new List<Form1>();

    public CustomContext()
    {
        CreateForm();
    }

    private void CreateForm()
    {
        Form1 form = new Form1();
        form.OpenNewForm += (sender, args) =>  CreateForm();
        form.Closed += (sender, args) => FormClosed(sender as Form1);
        _openForms.Add(form);
        form.Show();
    }

    private void FormClosed(Form1 form)
    {
        _openForms.Remove(form);
        if (_openForms.Count == 0)
        {
            ExitThread();
        }
    }
}

Program课程中,将主要内容更改为Run(..)新的上下文类:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new CustomContext());
}

然后在你的Form1中,确保你有一个事件,并触发该事件以打开新表单(请注意,在“真实”代码中我可能会抽象出来,或者很可能让我的DI容器处理注册,但这表明了更清楚的一点):

public event EventHandler OpenNewForm;
private void ButtonClick(object sender, EventArgs e)
{
    //instead of showing a new form, we just raise this event
    if (OpenNewForm != null) OpenNewForm(this, EventArgs.Empty);
}

这样做,是让ApplicationContext管理您的打开表单,以便在关闭 last 之前关闭第一个(或其中任何一个)不会退出应用程序。一旦最后一个表单关闭,它将退出应用程序。

答案 1 :(得分:1)

你可以用很多不同的方式做到这一点。有关您想要执行的操作示例,请在Program.cs文件中更改Main方法():

static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
            Form1 frm = new Form1();
            GlobalVariables.FormsList = new List<Form1>();  //new
            GlobalVariables.FormsList.Add(frm);             //new
            frm.Show();
            Application.Run();
        }

然后在每个Form1上都有一个实例化form1的新实例的按钮(或其他事件):

private void button1_Click(object sender, EventArgs e)
        {
            Form1 frm = new Form1();
            GlobalVariables.FormsList.Add(frm);     //new
            frm.Show();
        }

编辑:还将以下代码添加到FormClosing事件:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (GlobalVariables.FormsList.Count == 1)
    {
        Application.Exit();
    }
    else
    {
        GlobalVariables.FormsList.RemoveAt(GlobalVariables.FormsList.Count - 1);
    }
}

编辑:这是新的GlobalVariables类,其中包含有助于表单管理的表单列表:

   public class GlobalVariables
    {
       public static List<Form1> FormsList { get; set; }
    }

答案 2 :(得分:0)

如果您使用“x”按钮关闭表单,则不会影响其他表单。 如果您按代码关闭,则应正确获取该表单的对象并将其关闭。如果你能保留一份表格目录以便管理变得容易,那就更好了。

如果在两者之间涉及任何静态变量,则尝试在没有静态变量的情况下更改该逻辑,因为它们在对象之间共享。

答案 3 :(得分:0)

根据您想要做什么,您可以将Application.Run启动的表单作为仅启动其他表单的表单(例如您的文本编辑器表单)。

类似的东西:(这只是展示这个想法的一个例子。)

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Shown += Form1_Shown;
    }

    void Form1_Shown(object sender, EventArgs e)
    {
        TextEditorForm frm2 = new TextEditorForm(this);
        frm2.Show();
        this.Hide();
    }
}

public partial class TextEditorForm : Form
{
    Form1 frm1;

    public TextEditorForm(Form1 frm1)
    {
        InitializeComponent();
        this.frm1 = frm1;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm1.Show();
        this.Close();
    }
}