2013-07-02 117 views
3

我有两种窗体,子窗体通过buttonClick在Form1中调用/创建。现在我可以启动subForm,隐藏Form1,然后在subForm关闭时取消隐藏Form1。我希望能够做的是:隐藏主窗体,开始新窗体,在两个窗体之间切换而不关闭第二个窗体

  1. 如果用户点击changeform按钮,查看是否子窗体活跃,但隐藏
  2. 如果没有,则启动子窗体,否则隐藏Form1上,取消隐藏子窗体和控制传递给它
  3. 如果用户点击窗体的changeform按钮,隐藏窗体,取消隐藏Form1并控制传递给它
  4. 如果用户点击窗体的右上角的“X”,然后关闭应用程序,无论哪种形式是积极的。 (现在,选择“X”关闭子窗体并打开/取消隐藏Form1。)

我可以找到解决方案来完成部分要求(也许是所有的,我只是太小白知道)。在这里,从我刚才的问题重复一遍,我到目前为止的代码是:

Form1中

private void countClick(object sender, EventArgs e) 
    { 
     this.Hide(); 
     subForm myNewForm = new subForm(); 
     myNewForm.ShowDialog(); 
     this.Show(); 
     countSelect.Checked = false; 
    } 

和子窗体

private void totalClick(object sender, EventArgs e) 
    { 
     this.Close(); 
    } 

这工作,但它不是真正的优雅。

+0

的可能重复[隐藏表单,切换到第二形式,紧随其后的形式和取消隐藏第一种形式(HTTP://计算器。 COM /问题/ 17287361 /藏身一个外形交换机到一个秒外形紧密第二-FO rm-and-unhide-first-form) – musefan

+0

@musefan这是我原来的问题,这是由这里显示的代码片段回答的。 –

回答

2

我认为最好的办法是自己推出ApplicationContext。这使您可以完全控制应用程序的生命周期,而不必将其绑定到特定的窗口。有关更多信息,请参见http://msdn.microsoft.com/en-us/library/ms157901.aspx

下面是一个例子:

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new MyApplicationContext()); 
    } 
} 

public class MyApplicationContext : ApplicationContext 
{ 
    public MyApplicationContext() 
    { 
     ShowForm1(); 
    } 

    public void ShowForm1() 
    { 
     if (_form2 != null) 
      _form2.Hide(); 
     if (_form1 == null) 
     { 
      _form1 = new Form1(this); 
      _form1.FormClosed += OnFormClosed; 
     } 
     _form1.Show(); 
     MainForm = _form1; 
    } 

    public void ShowForm2() 
    { 
     if (_form1 != null) 
      _form1.Hide(); 
     if (_form2 == null) 
     { 
      _form2 = new Form2(this); 
      _form2.FormClosed += OnFormClosed; 
     } 
     _form2.Show(); 
     MainForm = _form2; 
    } 

    private void OnFormClosed(object sender, FormClosedEventArgs e) 
    { 
     if (_form1 != null) 
     { 
      _form1.Dispose(); 
      _form1 = null; 
     } 
     if (_form2 != null) 
     { 
      _form2.Dispose(); 
      _form2 = null; 
     } 
     ExitThread(); 
    } 

    private Form1 _form1; 
    private Form2 _form2; 
} 

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    public Form1(MyApplicationContext context) 
     : this() 
    { 
     _context = context; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     if (_context != null) 
      _context.ShowForm2(); 
    } 

    private readonly MyApplicationContext _context; 
} 

public partial class Form2 : Form 
{ 
    public Form2() 
    { 
     InitializeComponent(); 
    } 

    public Form2(MyApplicationContext context) 
     : this() 
    { 
     _context = context; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     if (_context != null) 
      _context.ShowForm1(); 
    } 

    private readonly MyApplicationContext _context; 
} 
0

为什么不能简单地将它们设置为前景,最上面的,等等? 并将它们反向设置?

---添加评论提议

+0

他*不*将父表格的引用传递给子表单,那么为什么你告诉他不要这样做? – Servy

+0

this.MainFormRef_Field = MainFormRef; 这是什么? – icbytes

+0

这是其他用户的答案,而不是OP。如果您想回应,也许您应该对该答案发表评论。 – Servy

-1

subForm访问MainForm

subForm创建一个构造函数和一个字段:

MainForm MainFormRef_Field; 
subForm(MainForm MainFormRef) 
{ 
    this.MainFormRef_Field = MainFormRef; 
} 

现在,您可以访问MainForm使用此参考。就像这样:

MainFormRef_Field.Show(); 
MainFormRef_Field.Hide(); //or how ever you want to handle it 

MainForm访问subForm

处理您subForm使用您为它创建的对象。在这里:

subForm myNewForm = new subForm(); 

要关闭整个应用程序,如果任何形式的关闭:

设置一个Form_Closing事件两种形式:

private void MainForm_Closing(object sender, EventArgs e) 
{ 
    Application.Exit(); 
} 

private void subForm_Closing(object sender, EventArgs e) 
{ 
    Application.Exit(); 
} 

注:

我我没有写出所有案例的整个代码。设置变量,检查条件。这完全取决于你如何编码。所有你需要的要点我已经为你提供了解决方案。

+0

我可以解释'-1'吗? – Shaharyar

+0

我没有这样做。不知道为什么它在那里。 –

+0

是不是我。但我把我的答案的一部分,在这里(因为它是指比业务方案的问题,更多的你的回答: 从子窗体访问父形式是不良作风和交叉引用 更好的方法是让子窗体弹出并响应对话结果等 或者对父窗体上的其他事件做出反应 但是不会将父项引用传递给子窗体 – icbytes

2

所以我们开始了前往子窗体并创建可用于当它要改变的形式通知家长一个新的事件:

public event Action ChangeForm; 

然后,我们触发事件和隐藏

private void ChangeForm_Click(object sender, EventArgs e) 
{ 
    Hide(); 
    if (ChangeForm != null) 
     ChangeForm(); 
} 

母体形式需要孩子形式的实例字段的一个实例:

私人窗体孩子=新子(当它要改变形式的子窗体);

,它需要初始化它在它的构造函数,既增加处理器的ChangeForm事件显示父,并到关闭事件来关闭自己:

public Form1() 
{ 
    InitializeComponent(); 

    child.ChangeForm +=() => Show(); 
    child.FormClosed += (s, args) => Close(); 
} 

然后,所有剩下的就是父形式可以隐藏自身,并显示孩子时,要改变形式:

private void ChangeForm_Click(object sender, EventArgs e) 
{ 
    Hide(); 
    child.Show(); 
} 
+0

感谢您的快速响应。所有谁回答。这是我采取的路线,所有工作正常。再次感谢。 –

+1

'form2.Closed + =(s,args)=> this.Close();'我可以知道这个声明如何工作?确切地说'(s,args)'是什么?使用lambda运算符(=>)? –

+0

@YashSaraiya声音就像你已经知道这是一个lambda,所以你可以简单地搜索你想知道它的任何内容。 – Servy

相关问题