我有这段代码:
Form1 newForm = new Form1();
newForm.Show();
//The rest of this code has been omitted
或多或少。 Form1仅用于示例目的。我的问题是我正在创建一个文本编辑器(基本上是我的上一个问题的延续),我希望能够同时打开多个Form1的副本。
这段代码允许我这样做,这很棒,但我希望能够关闭旧的,并且仍然在屏幕上显示newForm。目前,如果我关闭Form1,我会告别newForm。
这可能吗?我不想只是像记事本一样把所有的东西都白掉了。
答案 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();
}
}