1

我有我的Form1和我的Form2
Form1有一个方法可以访问一个将节点添加到它的方法TreeView

private void AddNode(TreeNode node)
{
  treeView1.Nodes.Add(node);
}

我想从我的访问这个方法,Form2但我有点坚持这样的事实

  • 静态 AddNode 方法将需要静态 treeView1,这是一种不好的做法。
  • Form2inside的一个新实例Form1将创建一个不同的实例,treeView1这不是我想要的。

此外,treeView1在设计器内部声明了,所以我不能真正将它的修饰符更改为静态(有人告诉我将静态控件放在表单中不是一个好主意)。

知道我该怎么做吗?

4

4 回答 4

3

我认为最好的选择是在 Form2 中创建事件并在 Form1 中订阅该事件。当您在 Form2 上做某事(例如用户点击按钮)时,会引发该事件(您也可以将一些参数作为事件参数传递)。

表格1:

private void StartForm2Button_Click(object sender, EventArgs e)
{
    Form2 form2 = new Form2();
    form2.SomethingHappened += Form2_SomethingHappened;
    form2.Show();
}

private Form2_SomethingHappened(object sender, EventArgs e)
{
    Form2 form2 = (Form2)sender;
    string data = form2.Data;
    // create node
    AddNode(node);
}

表格2:

public event EventHandler SomethingHappened;

public string Data
{
   get { return textBoxData.Text; }
}

private void SomeButton_Click(object sender, EventArgs e)
{
    if (SomethingHappened != null)
        SomethingHappened(this, EventArgs.Empty);
}

因此更新您所说的,从其他两种不同的表单创建的表单,那么您需要其他方式来订阅Form2事件。您可以从应用程序打开的表单集合中获取 form2。或者您可以在表单之间共享一些公共对象:

public class Model
{
    public event Action<string> DataAdded; // subscribe to this event in form1

    public void AddData(string data) // call this method in form2
    {
        if (DataAdded != null)
            DataAdded(data);
    }
}

好吧,在最好的世界里,我创建了一个模型,它将包含所有数据,并且只是将模型状态反映在Form1.

于 2012-12-12T15:48:47.090 回答
1

以下是一些需要将引用存储在某处的选项。这可能不是这种情况的最佳选择(或者可能取决于您的情况),但也发布了其他替代方案,因此请自行选择。


一种解决方案是您可以只对要使用的 Form1 实例进行静态引用。

static Form1 OpenForm1 = new Form1();

//in some other code
OpenForm1.MyFunction();

还有很多其他方法,重点是您需要确保您的 Form2 实例以某种方式引用了您的 Form1 实例。


另一种选择,您可以在创建 Form2 时传递实例:

例如作为属性...

//create Form2 from some where else
Form2 form2 = new Form2();
form2.ReferenceToForm1 = form1;

//in form2
public Form1 ReferenceToForm1 {get;set;}

//when needed in form2
ReferenceToForm1.MyFunction();
于 2012-12-12T15:41:53.740 回答
0

声明一个接口并传递 form2 对实现该接口的东西的引用。

例如:

public interface INodeAddable {
   void AddNode(TreeNode node);
}

public class Form1 : INodeAddable
{
    private void SomeMethod()
    {
        var f2 = new Form2(this);
    }

    public void AddNode(TreeNode n)
    {
       // add node to tree
    }
}

public class Form2
{
  private INodeAddable x;
  public Form2(INodeAddable x)
  {
    this.x = x;
  }

  public void SomeEventHandler(object sender, EventArgs e)
  {
     x.AddNode(someNewNode);
  }
}
于 2012-12-12T15:44:47.903 回答
0

使表单能够相互访问。

既然你说它们是从不同的形式产生的,一种方法是让共同的根知道它们的存在,并从它们的共同祖先那里建立联系。

我能想到的最好的方法是,如果这种行为是您将来会遇到的事情,那就是拥有一个基本的EventAggregator注入到所有表单中,通过它您可以将消息从一个传递到另一个,而无需紧密地传递它们耦合。有了它,您可以让 Form1 订阅 Form2 触发的事件,当触发该事件时,您将添加节点。

于 2012-12-12T15:51:59.770 回答