2014-03-13 57 views
5

在我的應用程序中,我有四種形式form1 form2 form3 form4。每個窗體都有兩個按鈕,即下一個和上一個按鈕之間切換窗體。和我的問題是如何可以切換窗體之間不創建新的窗體實例?下面是我的代碼如何在不創建表單的新實例的情況下切換表單?

在Form1:

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) 
    { 
     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()); 


    } 

在上面的代碼中,我創建的形式新的實例每次..,如何避免這一點,我怎麼能形式之間切換,而無需創建形式新實例....請幫我

+2

在全局類中保留一個公共的所有形式的靜態變量。在form1初始化函數中初始化form2,form3,form4。然後根據需要激活或隱藏。 – ray

+0

任何答案對你有幫助請標記爲答案 – Sumeshk

+0

謝謝你的建議.. – user3413736

回答

6

由於您正在訪問的形式依次只需確保您使用顯示方法將所有者分配給創建的表單並在創建後將其分配給類級別的變量。像這樣的東西應該適合你。

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(); 
    } 
} 
+0

謝謝先生,你的代碼建議真的非常感謝你,先生..... – user3413736

2

試試這個:

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

但這需要表格已經打開。而通過名字引用形式我稱之爲醜陋。 – PMF

+0

儘管@PMF的評論,這正是我所需要的!我能找到的每個其他案例都只是說實例化一個新的窗體實例......在我的情況下,我想操縱已經打開的當前窗體。 –

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

此功能可用於找出一個表單是否已打開或不

呼叫IsFormAlreadyOpen(Form4)如果返回true,這意味着Form4已經打開

你的情況

every forms constructor()

創建一個和前一個窗體對象

,並在按一下按鈕調用IsFormAlreadyOpen()找出表單是否已經打開,如果已經打開,只需將該表單打開即可 其他明智的顯示形式使用obj.show()方法 並隱藏或關閉父表單

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

可能是一個簡單的解決方案。您可以創建一個包含所需表單的靜態對象的類。所以你將能夠從任何形式的選擇中訪問所有這些表單,好處是它們被初始化一次。

public class formList 
{ 
     private static Form1 _form1 = new Form1(); 
     public static Form1 form1 { get {return _form1;} 
     ................. 
     ............ 
} 
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屬性。

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(); 

這工作順利,非常適合我。嘗試一下。

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#真的。但這應該工作。

相關問題