C# - 如何使两个窗体相互引用

6

我正在使用MS Visual C#编写WindowsForms应用程序,需要两个表单相互引用。在测试时,我在Form1上创建了两个按钮--一个按钮显示Form2,另一个按钮隐藏Form2(代码如下)。

我想为Form2做同样的事情--创建两个按钮来隐藏或显示Form1。我使用了与Form1相同的方法,但是当我编译应用程序时,似乎陷入了一个无限循环中,并出现StackOverflow消息。

我该如何更改代码,使得两个表单能够相互引用?

Form1代码:

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
    Form2 frm2;
    public Form1()
    {
        InitializeComponent();
        frm2 = new Form2();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm2.Visible = false;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        frm2.Visible = true;
    }
}
}

Form2 代码:

namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
    Form1 frm1;
    public Form2()
    {
        InitializeComponent();
        frm1 = new Form1();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm1.Visible = false;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        frm1.Visible = true;
    }
}
}

2
你应该为你的控件命名。 - SLaks
Form1和Form2的构造函数在一个无限循环中相互调用。 - Odrade
6个回答

8

Forms2的代码应该是

namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
    Form1 frm1;
    public Form2(Form1 parent)
    {
        InitializeComponent();
        frm1 = parent;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm1.Visible = false;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        frm1.Visible = true;
    }
}
}

尽管两者互相交流,但必须先创建一个并将其传递给第二个。要对Form1进行微调。
public Form1()
{
    InitializeComponent();
    frm2 = new Form2(this);
}

另一种方法是创建两个对象并在构建后传递它们。
namespace WindowsFormsApplication1
{
public class SomewhereElse
{
    public void SomeFunction()
    {
         Form1 form1= new Form1();
         Form2 form2= new Form2();

         form1.frm2 = form2;
         form2.frm1 = form1;
    }
}

public partial class Form2 : Form
{
    public Form1 frm1 {get; set;}
    public Form2(Form1 parent)
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm1.Visible = false;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        frm1.Visible = true;
    }
}

public partial class Form1 : Form
{
    public Form2 frm2 {get; set;}
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm2.Visible = false;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        frm2.Visible = true;
    }
}
}

感谢您的详细回复。我决定选择第一个选项。 - andrewl85

1
“Other form”需要分配给适当的实例。类似这样的东西应该会有所帮助。
public partial class TogglingForm : Form
{
    TogglingForm Other {get; set;}
    public TogglingForm()
    {
        InitializeComponent();
    }        

    private void HideOther_Click(object sender, EventArgs e)
    {
        Other.Visible = false;
    }

    private void ShowOther_Click(object sender, EventArgs e)
    {
        Other.Visible = true;
    }
}

....


static void Main()
{
   var first = new TogglingForm();
   var second = new TogglingForm {Other = first};
   first.Other = second;

   first.Show();
}   

0
namespace WindowsFormsApplication1 
{ 
public partial class Form2 : Form 
{ 
    Form1 frm1; 
    public Form2(Form1 frm1) 
    { 
        InitializeComponent(); 
        this.frm1 = frm1; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
        frm1.Visible = false; 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
        frm1.Visible = true; 
    } 
} 
} 

0
你在创建另一个表单时,每次都会创建一个新的实例。
相反,你应该让其中一个表单以其父表单的实例作为参数。

0
当您在frm1对象上创建Form2的实例时,此新实例将创建另一个Form1实例,该实例又创建一个新的Form2实例,以此类推...
您看到了无限循环吗?
在主类或全局应用程序变量中创建彼此的一个实例,或将它们作为参数传递给彼此。.NET框架将只是引用它们而不分配新的内存空间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接