简体   繁体   English

如何在C#中使用另一种Form(或另一类的一个类)中的方法

[英]How to use a method from one Form in another (or one class in another class) in C#

So, I have a treeview in Form2. 因此,我在Form2中有一个树形视图。 On a button click, in Form3 a code executes which inserts the text from the textboxes(from Form3) into the database, after that happens, I want the treeview in Form2 to update itself with those values from the database, which means I need to either use the treeView1(from Form2) in the code I write in Form3 or write a method in Form2(which I've done) to use in Form3. 在按钮上单击,在Form3中执行代码,将文本框(来自Form3)中的文本插入数据库中,然后,我希望Form2中的树形视图使用数据库中的值更新自身,这意味着我需要在我在Form3中编写的代码中使用treeView1(来自Form2),或者在Form2中编写一个方法(已完成)以在Form3中使用。

Method in Form2: Form2中的方法:

    public static void LoadTree()
    {
        int j = 1;
        string var;
        con.Open();
        OleDbCommand populate = new OleDbCommand("SELECT Project_name FROM Edit_Nodes ORDER BY Location ASC", con);
        OleDbDataReader reader = populate.ExecuteReader();
        while (reader.Read())
        {
            var = "H" + j + " - " + reader["Project_name"] + "";
            treeView1.Nodes[j].Text = var;
            j++;
        }
        con.Close();
    }

Problem : "Error 5 An object reference is required for the non-static field, method, or property 'Tool.Form2.con'" and so on for treeView1 and the other con's in the code. 问题:“错误5非静态字段,方法或属性'Tool.Form2.con'需要一个对象引用”,依此类推,treeView1和代码中的其他con都是如此。

Code in Form3: Form3中的代码:

   private void button1_Click(object sender, EventArgs e)
    {
       // more code here

      Form2.LoadTree();
    }

My question is how to solve these errors, OR....how do I directly make the program recognise treeView1 in Form3 (it belonging to Form2) so I can write the code again there. 我的问题是如何解决这些错误,或者....如何直接使程序识别Form3(属于Form2)中的treeView1,以便在那里再次编写代码。

First, make it an instance method instead of static: 首先,使其成为实例方法而不是静态方法:

public void LoadTree()
{
    // implementation
}

The reason static doesn't work is because it doesn't have the context of any given instance of the form, so it doesn't have the context of the controls on any given instance (such as treeView1 ). static不起作用的原因是因为它没有任何给定实例形式的上下文,因此它没有任何给定实例上控件的上下文(例如treeView1 )。 Next, you'll need the Form3 instance to have a reference to that particular Form2 instance. 接下来,您将需要Form3实例具有对该特定Form2实例的引用。 An easy way to do this is to add a property to Form3 and require a reference in its constructor. 一种简单的方法是在Form3添加一个属性,并在其构造函数中需要引用。 So, in Form3 : 因此,在Form3

private Form2 Form2Instance { get; set; }

public Form3(Form2 form2Instance)
{
    this.Form2Instance = form2Instance;
}

At this point any time you need to create an instance of Form3 , you need to supply it an instance of Form2 . 此时,无论Form3需要创建Form3的实例,都需要为其提供Form2的实例。 So if you create it from within Form2 then you'd do something like this: 因此,如果您在Form2创建它,则可以执行以下操作:

var form3Instance = new Form3(this);
form3Instance.Show();

At that point any instance of Form3 has a reference to the instance of Form2 which created it. 那时,任何Form3实例都引用了创建它的Form2实例。 So your code on Form3 can just reference the instance it has in that private property to call the method: 因此, Form3上的代码可以仅引用该私有属性中的实例来调用该方法:

private void button1_Click(object sender, EventArgs e)
{
    // more code here
    this.Form2Instance.LoadTree();
}

There're many issues with your code, see my comments 您的代码有很多问题,请参阅我的评论

  // Since you want to update treeView1 you should 
  // point out on which instance of Form1 the target treeView1 is.
  // That's why LoadTree() can't be static
  public void LoadTree() { // <- Not static!
    // Much better to use a local connection here
    //TODO: provide the right connection string here
    using(OleDbConnection con = new OleDbConnection(connectionString)) {
      con.Open();

      // wrap all local IDisposable into using(...) {...}
      using (OleDbCommand populate = new OleDbCommand(con)) {
        // Format out your SQL for it to be readble
        populate.CommandText = 
          "  select Project_Name\n" + 
          "    from Edit_Nodes\n" +
          "order by Location asc";

        // wrap all local IDisposable into using(...) {...}
        using (OleDbDataReader reader = populate.ExecuteReader()) {
          // When updating visual controls prevent them from constant re-painting
          // and annoying blinking
          treeView1.BeginUpdate();

          try {  
            // What is "j"? No-one knows; "loop" is more readable
            int loop = 1;

            while(reader.Read()) {
              // "var" is unreadable, "nodeText" is clear
              String nodeText = "H" + loop.ToString() + " - " + reader["Project_Name"];

              // Check ranges: what if SQL returns more recods than treeView1's nodes? 
              if (loop >= treeView1.Nodes.Count) 
                break;

              treeView1.Nodes[loop].Text = nodeText;

              loop += 1;
            }
          finally {
            treeView1.EndUpdate();
          }  
        }  
      }
    }

Now, it's time to call LoadTree() ; 现在,该调用LoadTree() but for which Form2 instance? 但是对于哪个 Form2实例? Imagine, that you've opened five Form2 's. 想象一下,您已经打开了五个 Form2 Now let's call LoadTree() for all Form2 instances: 现在让我们为所有Form2实例调用LoadTree()

private void button1_Click(object sender, EventArgs e) {
  // Enumerating all open forms
  foreach (Form form in Application.OpenForms) {
    Form2 source = form as Form2;

    // If the open form is Form2, call LoadTree
    if (!Object.ReferenceEquals(null, source))
      source.LoadTree();
  }
}

It looks like your operating on something called 'treeView1' in your LoadTree() method. 看起来您对LoadTree()方法中名为“ treeView1”的操作。 If this is part of the Form2 it will have to be static or you will have to call this method from an already instantiated object of it. 如果这是Form2的一部分,则它必须是静态的,或者您必须从已实例化的对象中调用此方法。

  1. Make treeView1 static 使treeView1静态
  2. Form2 form = new Form2(); Form2形式=新的Form2(); form.TreeView(); form.TreeView();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM