[英]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的一部分,则它必须是静态的,或者您必须从已实例化的对象中调用此方法。
Form2 form = new Form2(); Form2形式=新的Form2(); form.TreeView(); form.TreeView();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.