C# 如何从另一个类调整表单中的文本框属性?
我仍然无法了解如何从另一个类访问表单中的控件。我是 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();
}
}
}
这是类 print:
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!
我现在很沮丧,因为我无法从另一个班级访问它。
谁能一步步告诉我如何从打印类中调用它?我尝试了互联网上的许多步骤,但我就是无法得到它。
顺便说一句,我确实将文本框的修饰符设为公开。
i still cant get how to access the controls in the form from another class.im new to c# so my "try and error" method is not actually working.
can anyone give me a simple guide?
this is my code snippet
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();
}
}
}
This is class print:
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";
}
}
}
as you can see, im trying to change the textBox1 property in the print class.but when i compile it,im thrown with a System.StackOverflowException!
im getting frustrated now because i cant access it from another class.
can anyone give me a step by step on how to call it from the print class?i tried many steps from the internet but i just cant get it.
btw, i did make the modifier for the textbox to public.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
问题是
print.p
方法创建了一个新表单,并且该表单的构造函数再次调用print.p
方法。然后创建另一个新表单,其构造函数再次调用 print.p 方法,一遍又一遍地循环。这就是 StackOverflowException 的来源。解决方案是买一本教授面向对象编程的书。我知道这可能听起来很刻薄或没有帮助,但是您在问答网站上得到的答案都无法充分向您解释为什么您尝试做的事情是一个坏主意。像
print
这样的外部辅助类不应该能够干扰表单类的私有成员。相反,您应该调用表单类上的公共方法来进行这些修改。快速而肮脏的修复要求您找到一种方法来获取对
print.p
方法中表单类实例的引用。这是您能够调用该对象上的方法,而不是创建该类的新对象的唯一方法。一种方法是将引用作为参数传递给方法:此外,作为一个有点不相关的风格注释,您应该意识到几乎所有 C#(和 .NET 平台)的编码指南/约定都要求类的名称并且方法采用 PascalCased,而不是 CamelCased。因此,您的
print
类实际上应该命名为Print
。The problem is that
print.p
method creates a new form, and the form's constructor calls theprint.p
method again. Which then creates another new form, whose constructor calls theprint.p
method again, loop over and over. That's where theStackOverflowException
is coming from.The solution is to get a book that teaches object-oriented programming. I know that probably sounds snarky or unhelpful, but none of the answers you'll get on a Q&A website can adequately explain to you why what you're trying to do is a bad idea. External helper classes like
print
should not be able to mess with private members of your form class. Instead, you should call public methods on your form class that make these modifications.The quick-and-dirty fix requires that you figure out a way to get a reference to the instance of your form class in the
print.p
method. That's the only way you're going to be able to call methods on that object, rather than creating a new object of that class. One way is to pass a reference in to the method as a parameter:Also, as a somewhat irrelevant stylistic note, you should be aware that almost all coding guidelines/conventions for C# (and the .NET platform) require that the names of classes and methods be PascalCased, rather than camelCased. So, your
print
class should actually be namedPrint
.您收到
StackOverFlowException
是因为您使用以下代码在Form1
中创建了print
的新实例:在
print
的构造函数中,您创建一个Form1
的新实例,如下所示:它创建一个
print
的新实例,它创建一个Form1
的新实例code>Form1,它创建一个新实例print
,它创建一个Form1
的新实例,其中...您创建了一个无限循环,它杀死了堆栈。
You are getting a
StackOverFlowException
because you create a new instance ofprint
inForm1
using this code:Then in the constructor in
print
, you create a new instance ofForm1
like this:which creates a new instance of
print
, which creates a new instance ofForm1
, which creates a new instance ofprint
, which creates a new instance ofForm1
, which...You have created an infinite loop, which kills the Stack.
好吧,不知道为什么你想这样做(我不会),但你可以:
Okay, not sure why you want to do it like this (I wouldn't) but here you go:
最简单的方法就是简单地传递对新表单的引用。
然而,有许多设计模式可以帮助解决这个问题,例如 MVP 或 MVVM。然而,对于您当前的水平来说,它们可能有点高级。如果这只是一个简单的小项目,那么上面的代码就可以了。
The easiest way is simply pass a reference through to the new form.
There are a number of design patterns however, that can help with this, such as MVP or MVVM. However, they may be a little advanced for your current level. If this is only a simple small project, then the code above will do fine.
您的代码由于其他原因而存在问题(@CodyGray 解释了原因,这就是您收到 StackOverflowException 的原因),但通常您可以使用属性来允许访问,而无需暴露实际的
TextBox
控件本身;有关详细信息,请参阅此 MSDN 页面,例如:然后,在为了使用这个属性:
编辑:
由于评论中至少有一个挑剔,并且有足够的动机让至少一个人发现这一点“很棒”,我还将提供一种不同的方法,仍然使用该属性...
让我们假设目标是您想要在
p
中设置
文本,我们将只返回我们需要的内容:所以:
或者,您想要
获取
,或使用p
中的文本:这样:
The code you have is problematic for other reasons (@CodyGray explains the why, which is the reason you're getting a
StackOverflowException
), but in general you can use a property to allow access, without exposing the actualTextBox
control itself; see this MSDN page for plenty details, but for example:Then, in order to use this property:
EDIT:
Since there is at least one nitpick via comments, and sufficient incentive for at least one person to find that point 'great', I'll also offer a little different approach, still using the property...
Let's imagine the goal is that you want to
set
text inp
, we'll just return what we need:So that:
Or, you want to
get
, or use the text inp
:So that:
您不应该像这样跨类引用 UI 元素属性,这是不好的做法。
更好的方法是:
form1:
class print:
You should not reference UI element properties cross-class like this, it's bad practice.
a better way to do this would be :
form1:
class print:
在 print 类中使用它来获取表单
可以通过 p(fpassed) 调用它;
and in print class use this to get the form
can call it by p(fpassed);