如何在不创建新的表单实例的情况下在表单之间切换?

时间:2014-03-13 05:35:02

标签: c# .net winforms

在我的应用程序中,我有四个表单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();
    }

在Main:

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.Run(new Form1());


    }

在上面的代码中我每次都在创建表单的新实例..,我怎样才能避免这种情况以及如何在不创建表单的新实例的情况下在表单之间切换....请帮助我

8 个答案:

答案 0 :(得分:7)

由于您要按顺序访问表单,因此请确保使用Show Method将所有者分配给创建的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();
    }
}

答案 1 :(得分:4)

可能是一个简单的解决方案。您可以创建一个包含所需表单的静态对象的类。因此,您可以从您选择的任何形式访问所有这些表单,好的是它们被初始化一次。

public class formList
{
      private static Form1 _form1 = new Form1();
      public static Form1 form1 { get {return _form1;}
      .................
      ............
}

答案 2 :(得分:2)

试试这个:

Form1 myForm =(Form1) Application.OpenForms["Form1"];
myForm.Show();

答案 3 :(得分:2)

如果感兴趣的表单存在,您可以检查,如果不是创建,则可以

public static T OpenOrCreateForm<T>() 
  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<Form1>();
 }

private void Next_Click(object sender, EventArgs e)
{
   Hide();
   OpenOrCreateForm<Form3>();
}   

答案 4 :(得分:1)

  public bool IsFormAlreadyOpen(Type FormType)
        {
            foreach (Form OpenForm in Application.OpenForms)
            {
                if (OpenForm.GetType() == FormType)
                    return true;
            }
            return false;
        }

此功能可用于查明表格是否已经打开

如果它返回true则调用IsFormAlreadyOpen(Form4),这意味着Form4已经打开

在您的情况下

every forms constructor()中创建下一个和上一个表单对象

并在按钮单击调用IsFormAlreadyOpen()以查明表单是否已打开,如果已打开,只需将该表单放在前面 其他明智的方法是使用obj.show()方法显示表单 并隐藏或关闭父表格

答案 5 :(得分:0)

看起来你正在尝试实现类似向导的功能。我建议使用单一表格。然后,为其添加自定义选项卡控件。添加要在前一个和下一个上移动的表单按钮。

要自定义标签控件,您需要执行以下操作:

public class CustomWizard : TabControl
{
    /// <summary>
    /// This method traps windows message and hides other tabs in the tab control.
    /// Message trapped: TCM_ADJUSTRECT
    /// </summary>
    /// <param name="m">Reference to Windows message</param>
    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);
        }
    }

    /// <summary>
    /// This method traps the press to stop users from selecting tab page via keyboard
    /// </summary>
    /// <param name="ke">Event details</param>
    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属性。

答案 6 :(得分:0)

我有同样的问题。我需要的应用程序有很多表单,我需要向后向前切换表单而不丢失数据。我提出了以下解决方案,它对我有用。

在main(Program.cs)文件中,编写以下两个类:

static class Variables
{
    public static DataSet Configurations = new DataSet();

    public static float ExchangeRate = 0;

    public static Dictionary<string, int> ItemsCategories = new Dictionary<string, int>();

    public static Dictionary<string, float> WeightUnits = new Dictionary<string, float>();
}

static class Forms
{
    public static Form2 F_Form2 = new Form2();

    public static Form3 F_Form3 = new Form3();
}

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    /// 
    [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();

这对我来说非常顺利和完美。试试吧。

答案 7 :(得分:0)

只需删除第一个表单中的this.hide()和第二个表单中的[formNameHere].show();即可。

像这样:

表格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#真的。但这应该有用。