C# 如何调整另一个类的窗体中的文本框属性
本文关键字:窗体 文本 属性 另一个 何调整 调整 | 更新日期: 2023-09-27 17:50:22
我仍然无法了解如何从另一个 C# 新手 class.im 访问表单中的控件,所以我的"尝试和错误"方法实际上不起作用。
谁能给我一个简单的指南?
这是我的代码片段
表格1:
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";
}
}
}
如您所见,我试图更改打印类中的 textBox1 属性,但是当我编译它时,我抛出了一个 System.StackOverflowException!
我现在感到沮丧,因为我无法从另一个类访问它。
谁能给我一步一步地告诉我如何从打印课上调用它?我从互联网上尝试了很多步骤,但我就是无法得到它。
顺便说一句,我确实公开了文本框的修饰符。
问题是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,而不是驼峰。因此,您的print
类实际上应该命名为 Print
。
您得到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";
}
}
最简单的方法是简单地将引用传递给新表单。
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";
}
编辑:
由于至少有一次通过评论吹毛求疵,并且有足够的动力让至少一个人发现这一点"很棒",我还将提供一些不同的方法,仍然使用该属性......
假设目标是你想set
p
文本,我们只返回我们需要的东西:
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);
你不应该像这样跨类引用 UI 元素属性,这是不好的做法。
更好的方法是:
表格1:
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(已通过(调用它;
public static MainForm frm;
public MainForm(){
frm = this;
Yes()
}
public Yes(){
frm.textbox1.text = ":D";
}