[英]C# how to adjust textbox property in a form from another class?
我仍然无法获得如何从另一个class.im新的c#访问表单中的控件,所以我的“尝试和错误”方法实际上没有工作。
谁能给我一个简单的指南?
这是我的代码片段
Form1中:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
print pr = new print();
pr.p();
}
}
}
这是类打印:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsFormsApplication2
{
class print
{
public print()
{
}
public void p()
{
Form1 f = new Form1();
f.textBox1.Text = "change text";
}
}
}
正如你所看到的,我试图改变print类中的textBox1属性。但是当我编译它时,我抛出一个System.StackOverflowException!
我现在感到沮丧,因为我无法从另一个班级访问它。
任何人都可以一步一步地告诉我如何从打印类调用它?我尝试了从互联网上的许多步骤,但我不能得到它。
顺便说一句,我确实将文本框的修饰符设为公开。
问题是print.p
方法创建了一个新表单,表单的构造函数再次调用print.p
方法。 然后创建另一个新表单,其构造函数再次调用print.p
方法,一遍print.p
遍地循环。 这就是StackOverflowException
的来源。
解决方案是获得一本教授面向对象编程的书。 我知道这可能听起来很讽刺或无益,但你在问答网站上得到的答案都不能充分向你解释为什么你要做的事情是个坏主意。 像print
这样的外部帮助程序类不应该与表单类的私有成员混淆。 相反,您应该在表单类上调用进行这些修改的公共方法。
快速而肮脏的修复需要您找到一种方法来获取print.p
方法中对表单类实例的引用。 这是您能够在该对象上调用方法的唯一方法,而不是创建该类的新对象。 一种方法是将引用作为参数传递给方法:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
print pr = new print();
pr.p(this);
}
}
class print
{
public print()
{
}
public void p(Form frm)
{
frm.textBox1.Text = "change text";
}
}
另外,作为一个有点不相关的风格注释,您应该知道几乎所有C#(和.NET平台)的编码指南/约定都要求类和方法的名称是PascalCased,而不是camelCased。 因此,您的print
类实际上应该命名为Print
。
最简单的方法是将引用传递给新表单。
print pr = new print(textbox);
public print(Textbox textbox)
{
//do something with textbox.
}
然而,有许多设计模式可以帮助解决这个问题,例如MVP或MVVM。 但是,对于您当前的级别,它们可能会稍微提高一些。 如果这只是一个简单的小项目,那么上面的代码就可以了。
您拥有的代码由于其他原因而存在问题(@CodyGray解释了原因,这是您获得StackOverflowException
的原因),但通常您可以使用属性来允许访问,而不会暴露实际的TextBox
控件本身; 有关详细信息,请参阅此MSDN页面 ,但例如:
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
}
public string FormText
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
}
}
然后,为了使用此属性:
public void p()
{
Form1 f = new Form1();
f.FormText = "change text";
}
编辑:
由于通过评论至少有一个挑剔,并且至少有一个人有足够的动机去寻找“伟大”这一点,我还会提供一些不同的方法,仍然使用该属性......
让我们想象一下,目标是你要在p
set
文本,我们只需返回我们需要的内容:
public string p()
{
return "change text";
}
以便:
myFormReferenceSomewhereNotInPrintClass.FormText = myPrintClassInstance.p();
或者,您想要get
或使用 p
的文本:
public void p(string text)
{
//do your thing with the text
}
以便:
myPrintClassInstance.p(myFormReferenceSomewhereNotInPrintClass.FormText);
您将获得StackOverFlowException
因为您使用以下代码在Form1
创建了一个新的print
实例 :
print pr = new print();
然后在print
中的构造函数中,创建一个Form1
的新实例,如下所示:
Form1 f = new Form1();
这将创建一个新的print
实例,它创建一个Form1
的新实例,它创建一个新的print
实例,它创建一个Form1
的新实例,其中...
您创建了一个无限循环,它会杀死堆栈。
好吧,不知道你为什么要这样做(我不愿意)但是你走了:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
print pr = new print();
pr.p(this);
}
}
public class print
{
public print() {}
public void p(Form1 f)
{
f.textBox1.Text = "change text";
}
}
public static MainForm frm;
public MainForm(){
frm = this;
Yes()
}
public Yes(){
frm.textbox1.text = ":D";
}
你不应该像这样引用跨元素的UI元素属性,这是不好的做法。
更好的方法是:
Form1中:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
print pr = new print();
textBox1.Text = pr.p();
}
}
}
班级印刷:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsFormsApplication2
{
class print
{
public print()
{
}
public string p()
{
return "change text";
}
}
}
public Form1()
{
InitializeComponent();
print pr = new print(this);
pr.p();
}
在印刷类中使用它来获取表格
{
Form fpassed;
public print(Form f)
{
fpassed = f;
}
public void p(Form f)
{
f.textBox1.Text = "change text";
}
}
可以通过p(fpasssed)来调用它;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.