如何在不创建新的表单实例的情况下在表单之间切换?
在我的应用程序中,我有四个表单form1 form2 form3 form4。每个表单有两个按钮,即下一个和上一个按钮,可以在表单之间切换。我的问题是如何在不创建新的表单实例的情况下在表单之间切换? 下面是我的代码
在Form1中:
public Form1() { InitializeComponents(); } private void Next_Click(object sender, EventArgs e) { this.Hide() Form2 form2 = new Form2(); form2.Show(); }
在Form2中:
public Form2() { InitializeComponents(); } private void Previous_Click(object sender, EventArgs e) { this.Hide(); Form1 form1 = new Form1(); form1.Show(); } private void Next_Click(object sender, EventArgs e) { this.Hide(); Form3 form3 = new Form3(); form3.Show(); }
在Form3中:
public Form3() { InitializeComponents(); } private void Previous_Click(object sender, EventArgs e) { this.Hide(); Form2 form2 = new Form2(); form2.Show(); } private void Next_Click(object sender, EventArgs e) { this.Hide(); Form4 form4 = new Form4(); form4.Show(); }
在Form4中:
public Form4() { InitializeComponents(); } private void Previous_Click(object sender, EventArgs e) { this.Hide(); Form3 form3 = new Form3(); form3.Show(); }
在主要:
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); }
在上面的代码我每次都在创建表单的新实例..,我怎样才能避免这种情况以及如何在不创建表单的新实例的情况下在表单之间切换….请帮助我
由于您要按顺序访问表单,因此请确保使用Show方法将所有者分配给创建的Form,并在创建后将其分配给类级别变量。 这样的事情对你有用。
Form1中
public partial class Form1 : Form { Form2 frm2; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if (frm2 == null) { frm2 = new Form2(); //Create form if not created frm2.FormClosed += frm2_FormClosed; //Add eventhandler to cleanup after form closes } frm2.Show(this); //Show Form assigning this form as the forms owner Hide(); } void frm2_FormClosed(object sender, FormClosedEventArgs e) { frm2 = null; //If form is closed make sure reference is set to null Show(); } }
窗体2
public partial class Form2 : Form { Form3 frm3; public Form2() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Owner.Show(); //Show the previous form Hide(); } private void button2_Click(object sender, EventArgs e) { if (frm3 == null) { frm3 = new Form3(); frm3.FormClosed += frm3_FormClosed; } frm3.Show(this); Hide(); } void frm3_FormClosed(object sender, FormClosedEventArgs e) { frm3 = null; Show(); } }
Form3
public partial class Form3 : Form { public Form3() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Owner.Show(); Hide(); } }
可能是一个简单的解决方案 您可以创建一个包含所需表单的静态对象的类。 因此,您可以从您选择的任何forms访问所有这些表单,好的是它们被初始化一次。
public class formList { private static Form1 _form1 = new Form1(); public static Form1 form1 { get {return _form1;} ................. ............ }
试试这个:
Form1 myForm =(Form1) Application.OpenForms["Form1"]; myForm.Show();
您可以检查感兴趣的表单是否存在 ,如果不存在则:
public static T OpenOrCreateForm() where T: Form, new() { T result; // Test if form exists foreach(Form form in Application.OpenForms) { result = form as T; if (!Object.ReferenceEquals(null, result)) { // Form found; and this is the right place // to restore form size, // bring form to front etc. if (result.WindowState == FormWindowState.Minimized) result.WindowState = FormWindowState.Normal; result.BringToFront(); return result; } } // Form doesn't exist, let's create it result = new T(); // Probably, you want to show the created form result.Show(); resturn result; } ... private void Previous_Click(object sender, EventArgs e) { Hide(); OpenOrCreateForm(); } private void Next_Click(object sender, EventArgs e) { Hide(); OpenOrCreateForm(); }
public bool IsFormAlreadyOpen(Type FormType) { foreach (Form OpenForm in Application.OpenForms) { if (OpenForm.GetType() == FormType) return true; } return false; }
此function可用于确定表单是否已打开
如果它返回true则调用IsFormAlreadyOpen(Form4)
,这意味着Form4已经打开
在你的情况下
在every forms constructor()
创建下一个和上一个表单对象
并在按钮单击调用IsFormAlreadyOpen()以查明表单是否已打开,如果已经打开,只需将该表单放在前面另外明智地使用obj.show()方法显示表单并隐藏或关闭父表单
看起来你正在尝试实现类似向导的function。 我建议使用单一表格。 然后,向其添加自定义选项卡控件。 添加按钮以形成上一个和下一个的移动。
要自定义选项卡控件,您需要执行以下操作:
public class CustomWizard : TabControl { /// /// This method traps windows message and hides other tabs in the tab control. /// Message trapped: TCM_ADJUSTRECT /// /// Reference to Windows message protected override void WndProc(ref Message m) { // Second condition is to keep tab pages visible in design mode if (m.Msg == 0x1328 && !DesignMode) { m.Result = (IntPtr)1; } else { base.WndProc(ref m); } } /// /// This method traps the press to stop users from selecting tab page via keyboard /// /// Event details protected override void OnKeyDown(KeyEventArgs ke) { if (ke.Control && ke.KeyCode == Keys.Tab) return; base.OnKeyDown(ke); } private void InitializeComponent() { this.SuspendLayout(); this.ResumeLayout(false); } }
此选项卡控件一次只显示一个选项卡。 虽然,在设计时你可以看到它们。 将此按钮添加到表单中。 单击按钮,仅设置此选项卡控件的SelectedIndex
属性。
我遇到过同样的问题。 我需要的应用程序有很多表单,我需要向后向前切换表单而不会丢失数据。 我提出了以下解决方案,它对我有用。
在main(Program.cs)文件中,编写以下两个类:
static class Variables { public static DataSet Configurations = new DataSet(); public static float ExchangeRate = 0; public static Dictionary ItemsCategories = new Dictionary(); public static Dictionary WeightUnits = new Dictionary(); } static class Forms { public static Form2 F_Form2 = new Form2(); public static Form3 F_Form3 = new Form3(); } static class Program { /// /// The main entry point for the application. /// /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } }
第一个类用于可以跨表单使用的全局变量。 您可以访问任何变量:
Variables.ExchangeRate = 7.2; //(for ex).
第二个类是您定义所有表单的新实例的地方。 您可以隐藏n在所有表单中的任何位置显示它们:
Forms.F_Form3.Show();
要么
Forms.F_Form2.Hide();
这对我来说非常顺利和完美。 试试吧。
只需删除第一个表单中的this.hide()
和[formNameHere].show();
在第二种forms。
像这样:
表格1:
public Form1() { InitializeComponents(); } private void Next_Click(object sender, EventArgs e) { this.Hide() Form2 form2 = new Form2(); form2.Show(); }
表格2:
public Form2() { InitializeComponents(); } private void Previous_Click(object sender, EventArgs e) { Form1 form1 = new Form1(); this.Hide(); } private void Next_Click(object sender, EventArgs e) { Form3 form3 = new Form3(); this.Hide(); }
等等。不善于解释,而且用C#真的。 但这应该有效。