Reputation: 2153
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.
Upvotes: 4
Views: 5142
Reputation: 1
public static MainForm frm;
public MainForm(){
frm = this;
Yes()
}
public Yes(){
frm.textbox1.text = ":D";
}
Upvotes: 0
Reputation: 45058
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 actual TextBox
control itself; see this MSDN page for plenty details, but for example:
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
}
public string FormText
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
}
}
Then, in order to use this property:
public void p()
{
Form1 f = new Form1();
f.FormText = "change text";
}
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 in p
, we'll just return what we need:
public string p()
{
return "change text";
}
So that:
myFormReferenceSomewhereNotInPrintClass.FormText = myPrintClassInstance.p();
Or, you want to get
, or use the text in p
:
public void p(string text)
{
//do your thing with the text
}
So that:
myPrintClassInstance.p(myFormReferenceSomewhereNotInPrintClass.FormText);
Upvotes: 1
Reputation: 4127
public Form1()
{
InitializeComponent();
print pr = new print(this);
pr.p();
}
and in print class use this to get the form
{
Form fpassed;
public print(Form f)
{
fpassed = f;
}
public void p(Form f)
{
f.textBox1.Text = "change text";
}
}
can call it by p(fpassed);
Upvotes: 0
Reputation: 11100
The easiest way is simply pass a reference through to the new form.
print pr = new print(textbox);
public print(Textbox textbox)
{
//do something with textbox.
}
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.
Upvotes: 1
Reputation: 3604
Okay, not sure why you want to do it like this (I wouldn't) but here you go:
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";
}
}
Upvotes: 1
Reputation: 17176
You are getting a StackOverFlowException
because you create a new instance of print
in Form1
using this code:
print pr = new print();
Then in the constructor in print
, you create a new instance of Form1
like this:
Form1 f = new Form1();
which creates a new instance of print
, which creates a new instance of Form1
, which creates a new instance of print
, which creates a new instance of Form1
, which...
You have created an infinite loop, which kills the Stack.
Upvotes: 1
Reputation: 245012
The problem is that print.p
method creates a new form, and the form's constructor calls the print.p
method again. Which then creates another new form, whose constructor calls the print.p
method again, loop over and over. That's where the StackOverflowException
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:
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";
}
}
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 named Print
.
Upvotes: 5
Reputation: 8652
You should not reference UI element properties cross-class like this, it's bad practice.
a better way to do this would be :
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();
}
}
}
class print:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsFormsApplication2
{
class print
{
public print()
{
}
public string p()
{
return "change text";
}
}
}
Upvotes: 0