2017-08-12 54 views
1

我是新的C#和已经创建了一个基本程序。标签式菜单 - 每个标签作为一个单独的CS文件

我的“主菜单”被设定与沿前7个标签。 我已成立CASE所以当用户选择的标签它增加了该特定子菜单(frmXXXmenu)与对照。

的问题是

  1. 这是正确的
  2. 现在每个窗体将打开每一次点击,因此我一直的形式生成实例(我可以看到我的进程内存增加!)

    private void tabmain_SelectedIndexChanged(object sender, EventArgs e) 
    { 
        string curtab = tabmain.SelectedTab.Name.ToString(); 
        switch (tabmain.SelectedTab.Name) 
        { 
         case "tabcollect": 
          frmcollectmenu frmcollectmenu = new frmcollectmenu(); 
          frmcollectmenu.TopLevel = false; 
          tabcollect.Controls.Add(frmcollectmenu); 
          frmcollectmenu.Dock = DockStyle.Fill; 
          frmcollectmenu.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
          frmcollectmenu.Show(); 
          break; 
         case "tabpack": 
          frmpackmenu frmpackmenu = new frmpackmenu(); 
          frmpackmenu.TopLevel = false; 
          tabpack.Controls.Add(frmpackmenu); 
          frmpackmenu.Dock = DockStyle.Fill; 
          frmpackmenu.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
          frmpackmenu.Show(); 
          break; 
    
    
        } 
    } 
    

等7个选项卡。

上午我在正确的方向,如果是这样,我怎么解决这个实例的情况呢?

我想无论是处置时不再是活动..或者当一个已经打开有点不创建一个新的实例?

第二问题

之一形式需要约2秒至打开(它是示出基于SQL的图表)。我怎样才能加载这个页面在标签中,当我打开frmmain()来启动程序,然后当我打开它将被加载的选项卡? 我试图把

frmcollectmenu frmcollectmenu = new frmcollectmenu(); 
    frmcollectmenu.TopLevel = false; 
    tabcollect.Controls.Add(frmcollectmenu); 
    frmcollectmenu.Dock = DockStyle.Fill; 
    frmcollectmenu.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
frmcollectmenu.visible = false; 
frmcollectmenu.Show(); 

(添加的可见部分),然后我做到了再次可见选择的选项卡时,但似乎它仍然需要几秒钟,并没有真正工作的权利。

+0

的启动时间?它是否不像你预期的那样行事,是不是编译? –

+1

@YvetteColomb它编译,但是当他们打开更多的情况下,该进程的内存每一次上升。这显然不是'好技术',所以我正在学习如何变得更聪明:) –

回答

0

如果你想你的表格只有一个实例打开,那么你应该检查Application.OpenForms集合,如果你的形式之一已经由系统

case "tabcollect": 
    frmcollectmenu f = Application.OpenForms["frmcollectmenu"]; 
    if(f == null) 
    { 
     frmcollectmenu frmcollectmenu = new frmcollectmenu(); 
     frmcollectmenu.TopLevel = false; 
     tabcollect.Controls.Add(frmcollectmenu); 
     frmcollectmenu.Dock = DockStyle.Fill; 
     frmcollectmenu.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
     frmcollectmenu.Show(); 
    } 
    else 
     f.Show(); 
    break; 

通知所涉及那里,如果你离开了这个工程将表单的名称属性设置为其默认名称(与表单的类名称相同)

您还可以尝试在每个表单的单独方法中分隔关于打开表单的逻辑,并实现一个字典,您在其中存储该表单键和当用户选择该特定标签时执行的动作

// At form global level.... 
    Dictionary<string, Action> tabActions = new Dictionary<string, Action>() 
    { 
    { "tabCollect", runCollect }, 
    { .....     }, 
     so on for other tabs 
    } 

    // The logic for a particular form (the same are needed for others forms) 
    private static void runCollect() 
    { 
    frmcollectmenu f = Application.OpenForms["frmcollectmenu"]; 
    if(f == null) 
    { 
     frmcollectmenu frmcollectmenu = new frmcollectmenu(); 
     frmcollectmenu.TopLevel = false; 
     tabcollect.Controls.Add(frmcollectmenu); 
     frmcollectmenu.Dock = DockStyle.Fill; 
     frmcollectmenu.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
     frmcollectmenu.Show(); 
    } 
    else 
     f.Show(); 
    } 

现在,你可以在你的SelectedIndexChanged方法删除开关,只是选择从词典中适当的行动静态建立在什么程序做你的主要形式

private void tabmain_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    string curtab = tabmain.SelectedTab.Name.ToString(); 
    if(tabActions.ContainsKey(curTab)) 
     tabActions[curTab].Invoke(); 
} 
+0

那么,我做一个,B,C,D,E为每个其他形式的情况? 有没有办法或许可以在案例开始之前“Form open = Application.OpenForms [openfrm];”或者其他东西,然后openfrm = Application.OpenForms [“frmcollectmenu”]; –

+0

只有在切换后才知道要检查哪种格式。您可以创建一个字典,其中键是选项卡名称,值是一个函数委托,它运行您需要创建或重新显示特定窗体的特定代码。但我认为这不是一个很大的区别。 – Steve

+0

谢谢,我喜欢这个方法的想法,似乎有点清洁? –

相关问题