在StackOverflow上有大量的问题,询问如何隐藏Form1和显示Form2。通常情况下,有几个不同的答案:
1)
// Program.cs
Application.Run(new Form1());
// Form1.cs
Form2 form2 = new Form2();
form2.Show();
this.Hide();2)
// Program.cs
Form1 form1 = new Form1();
Form2 form2 = new Form2();
form1.Show();
form2.Show();
Application.Run();...etc..
我不是在寻找像#1这样的简单的一次性解决方案,我在寻找最好的表单管理实践。一个有5-8个表单的应用程序,频繁地打开和关闭另一个表单--管理这些表单的最佳方法是什么?
我的想法是把每一种形式都变成一种(懒惰?)并将它们掩埋在某种类型的FormsManager类中(比如解决方案2,但++)。然后单独的表单可能会调用类似于FormsManager.GetForm<WelcomeDialog>()的东西。
但我想知道有更多经验的人用的是什么。同样,这些解决方案不应该是快速攻击。它们应该是design-oriented,,或许是architectural,和的长期解决方案。
编辑:
对于任何可能遇到同样问题的人来说,这都是一个相当普遍的问题(所以需求是非常开放的)。不过,我不需要在启动时显示多个表单。而且,我没有MDI表单。我可能有一些模态形式,但它们大多是非模态的.
发布于 2012-02-27 10:17:38
我在这里以一般的方式回答。
我认为单例模式不适合表单管理。通常,您希望向窗体传递某些上下文参数,并且可能希望打开同一窗体的多个实例。所以单身人士不太适合我。
我认为表单管理应该很简单。
例如,如果您想从另一个表单中显示一个模态表单,我会编写一些非常简单的内容:
private void button1_Click(object sender, EventArgs e)
{
using (ModalForm1 frm = new ModalForm1(myParam))
{
frm.ShowDialog();
if (frm.MyResultProperty == ...)
{
// Do some job here
}
}
}当然,您可以编写一些接口/泛型语法,以避免一些代码重复,以防您想要显示很多模态形式:
public interface IFormResult<T>
{
T Result { get; set; }
}
public class ModalForm1 : Form, IFormResult<string>
{
public ModalForm1()
{
InitializeComponent();
this.Result = "My result";
}
public string Result { get; set; }
}
private void button1_Click(object sender, EventArgs e)
{
string res = ShowModalForm<ModalForm1, string>();
}
private static T2 ShowModalForm<T1, T2>()
where T1 : Form, IFormResult<T2>, new()
{
using (T1 form = new T1())
{
form.ShowDialog();
return form.Result;
}
}但说实话,我觉得有点过火了。
第二点:如果表单没有完全遵循这个特定的行为(ShowDialog()然后设置了一个Result属性),那么您必须编写另一个Interface...etc。
如果这种类型的语法(泛型,interfaces...etc)。它不会减少编写的代码行数或复杂度或可维护性(很显然,我们不能说这是真的),那么它就非常无用了。
编辑:
表单管理实际上取决于您的用例。
FormManager概念(或者更好一些:考虑如何通过减少可能打开的表单的数量来提高用户体验),如果您有一些相对简单的东西(2-3种非模态表单同时+ 3-4种可能的模式表单),那么我不会编写复杂的代码来管理这些表单。通常,用于启动应用程序的表单(即关闭时停止程序的表单,即作为Application.Run()参数的表单)负责其他表单。您有一个主窗体和多个子窗体。如果您的情况确实不同,那么可能有一些更聪明的东西可以编写,但它将取决于您的情况。我不认为一个人能为表单管理的一般问题提供一个通用的好答案。
老实说,如果您想要一些真正可维护的东西,请尽量减少(尽可能多地)可以同时显示的表单数量。在大多数情况下,多个显示的非模式表单不能提供良好的用户体验,如果表单相互依赖,表单生命周期管理可能会出现问题。
发布于 2012-11-15 22:12:58
除了最简单的场景--在应用程序的生命周期中运行的单个主窗体(具有短暂的子窗体) --建议创建一个继承自ApplicationContext的类。也没那么复杂:
class FormManager : ApplicationContext {
//When each form closes, close the application if no other open forms
private void onFormClosed(object sender, EventArgs e) {
if (Application.OpenForms.Count == 0) {
ExitThread();
}
}
//Any form which might be the last open form in the application should be created with this
public T CreateForm<T>() where T : Form, new() {
var ret = new T();
ret.FormClosed += onFormClosed;
return ret;
}
//I'm using Lazy here, because an exception is thrown if any Forms have been
//created before calling Application.SetCompatibleTextRenderingDefault(false)
//in the Program class
private static Lazy<FormManager> _current = new Lazy<FormManager>();
public static FormManager Current => _current.Value;
//Startup forms should be created and shown in the constructor
public FormManager() {
var f1 = CreateForm<Form1>();
f1.Show();
var f2 = CreateForm<Form2>();
f2.ShowDialog();
}
}而Application.Run在Program.cs中可以使用FormManager的静态实例。
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(FormManager.Current);
}
}在应用程序的生存期内,应该通过CreateForm创建新的表单,以便将onFormClosed方法注册到FormClosed事件:
var f3 = FormManager.Current.CreateForm<Form3>();
f3.Show();
var f4 = FormManager.Current.CreateForm<Form4>();
f4.ShowDialog();如果您更喜欢new Form3();而不是对FormManager.CreateForm的调用,则可以在FormManager上创建RegisterForm方法
public void RegisterForm(Form frm) {
frm.FormClosed += onFormClosed;
}并在每个新的RegisterForm上调用Form
var f3 = new Form3();
FormManager.Current.RegisterForm(f3);
var f4 = new Form4();
FormManager.Current.RegisterForm(f4);(注:如果您的所有表单都继承自某个基类,那么可以在基类构造函数中调用它,而不是手动调用每个新实例的RegisterForm。)
注意,Application.OpenForms只返回当前可见的那些表单。如果应用程序不应该退出,只要仍然有隐藏表单打开,那么FormManager将不得不使用一些集合来跟踪所有表单。该集合将决定是否退出应用程序。
class FormManager : ApplicationContext {
private List<Form> forms = new List<Form>();
private void onFormClosed(object sender, EventArgs e) {
forms.Remove((Form)sender);
if (!forms.Any()) {
ExitThread();
}
}
public void RegisterForm(Form frm) {
frm.FormClosed += onFormClosed;
forms.Add(frm);
}
public T CreateForm<T>() where T : Form, new() {
var ret = new T();
RegisterForm(ret);
return ret;
}
private static Lazy<FormManager> _current = new Lazy<FormManager>();
public static FormManager Current => _current.Value;
}发布于 2012-02-27 09:54:36
根据应用程序的大小,您可以查看Microsoft库,特别是CAB块。
这应该会给你一个好的开始。
https://stackoverflow.com/questions/9462592
复制相似问题