I apologize in advance with what will probably be a fairly easy/quick answer based on scope, but I've looked everywhere and am surprised to not come up with an answer.
I have created a class called Soldier with roughly 100 class variables. I need a user to enter information and gradually build a Solider object over the course of several different class Forms (because there is too much data to collect on just one).
I create an (empty) instance of a Soldier (tempSoldier) in Form1.cs and start to set the object's class variables that I collect from the user.
private void button1_Click(object sender, EventArgs e)
{
Soldier tempSoldier = new Soldier();
tempSoldier.surname = textbox1.text;
}
My question: how do I gain access to the object instance (tempSoldier) from Form1.cs in the other classes (Form2.cs, Form3.cs ...)?
I should mention that all of the Forms (Form1.cs, Form2.cs ...) share the same namespace.
Thanks in advance
Edit: All solutions below work so it just depends upon which one you like the best. Thank you for your feedback.
One little note, make sure you make ALL of the class modifiers Public including your custom class (in my case Soldier.cs).
You'll need to declare the Soldier instance in in a higher scope.
One way of doing this would be to declare it inside Form1, then pass it to Form2, and so on.
public class Form1
{
private Soldier tempSoldier = new Soldier();
private void button1_Click(object sender, EventArgs e)
{
tempSoldier = new Soldier();
tempSoldier.surname = textbox1.text;
}
private void GotoNextStep()
{
// pass the existing instance to the next form
Form2 form2 = new Form2(tempSoldier);
// display form 2 ...
}
}
Another possibility is to use a singleton variable in a class that all the forms have access to.
public class MyAppManager
{
private static readonly Soldier _soldier = new Solider();
public static Soldier SoldierInstance
{
get { return _soldier; }
}
}
private void button1_Click(object sender, EventArgs e)
{
MyAppManager.SoldierInstnace.surname = textbox1.text;
}
The former approach is ok if there's a distinct sequence to the forms; the latter is better if difference forms could be used at different times or revisited.
You can also make Soldier a static variable :
public static Soldier soldier {get;set;}
private void button1_Click(object sender, EventArgs e)
{
soldier = new Soldier();
soldier.surname = textbox1.text;
}
Code in other forms:
Form1.soldier.name ="";
You should create a public property on your form that exposes the soldier. You can then access this property from the other forms.
// ...
public Soldier Soldier { get; private set; }
private void button1_Click(object sender, EventArgs e)
{
Soldier tempSoldier = new Soldier();
tempSoldier.surname = textbox1.Text;
this.Soldier = tempSoldier;
}
// ...
Your Form2 class could look something like this:
public partial class Form2
{
private Form1 form1;
public Form2(Form1 form1)
{
this.form1 = form1;
this.InitializeComponent();
}
public void DoStuffWithForm1()
{
// ...
string surname = this.form1.Soldier.surname;
// ...
}
}
In your other class, create a method with objects as parameters.
public class TryMe (TextBox newTextbox) {
newTextbox.Text = "Hello this is a text."
//You can also get the value of textbox of another form
var textString = newTextbox.Text;
}
And then in your main form, call that method with your objects as parameters. In this case, add textbox1 to your method's parameter.
Your code in form:
TryMe(textbox1);
Related
I have seen a few links on attempts at this but I haven't found a solution. I am attempting to access my form textbox and update it with text from another class. I can update the text within my DataOrganizerForm class directly but when I pass text back to the DataOrganizerForm class then it doesn't update on the GUI. Here is what I have:
public partial class DataOrganizerForm : Form
{
//Default constructor
public DataOrganizerForm()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
//Handle a Start/Stop button click
private void start_stop_button_Click(object sender, EventArgs e)
{
SerialNumberSearcher snsearch = new SerialNumberSearcher();
snsearch.searchSN();
}
//Allow simple access to update to notification textbox
public void setNotificationText(string text)
{
notification_textbox.Text = text;
}
}
public class SerialNumberSearcher
{
public void searchSN()
{
DataOrganizerForm formAccess = new DataOrganizerForm();
formAccess.setNotificationText("Updated text from different class");
}
}
Well, it won't update the textbox 'cause you're instantiating another object of the DataOrganizerForm class. What you could do is passing a reference of the form object to the SerialNumberSearcher, like this:
public class SerialNumberSearcher
{
private readonly DataOrganizerForm _form;
public SerialNumberSearcher(DataOrganizerForm form)
{
_form = form;
}
public void searchSN()
{
_form.setNotificationText("Updated text from different class");
}
}
You need to understand at which instance you operate. When you use the new-eperator you create a new instance, like a new copy of that type.
DataOrganizerForm formAccess = new DataOrganizerForm();
The original Form is a different instance then the one you create in the searchSN method.
You need to pass that instance into the method to manipulate it:
public void searchSN(DataOrganizerForm formAccess )
{
formAccess.setNotificationText("Updated text from different class");
}
When you want to call this method you need to use this to reference the current object :
private void start_stop_button_Click(object sender, EventArgs e)
{
SerialNumberSearcher snsearch = new SerialNumberSearcher();
snsearch.searchSN(this);
}
this will access the current instance of the Form, thereby allowing you to manipulate the textbox that you are interested in.
When do you use the “this” keyword? might also be helpfull
Thanks for the help. This is what I was able to do to make my application work. I passed the Textbox object by reference to my other class and was able to display my information that way. Also, I had issues getting my text box to continuously update. I had to add
public partial class DataOrganizerForm : Form
{
//Default constructor
public DataOrganizerForm()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
//Handle a Start/Stop button click
private void start_stop_button_Click(object sender, EventArgs e)
{
SerialNumberSearcher snsearch = new SerialNumberSearcher();
snsearch.searchSN(notification_textbox);
}
//Allow simple access to update to notification textbox
public void setNotificationText(string text)
{
notification_textbox.Text = text;
notification_textbox.Update();
}
}
public class SerialNumberSearcher
{
public void searchSN(Textbox notifyTextbox)
{
notifyTextbox.setNotificationText = "Updated text from different class";
notifyTextbox.Update();
}
}
Still in the process of learning C#, but I'm a bit confused on something here.
For example, I have a textbox on my form and it has the name of testTXT. Based on the code below, I've created a new class outside of the public partial one that's there by default, and now I'm trying to access testTXT but I cannot. I'm going to also need to access several other textboxes and things later on as well.
Here's a snippet of the code I'm working with thus far:
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void testButton_Click(object sender, EventArgs e)
{
GeneratedClass gc = new GeneratedClass();
gc.CreatePackage("C:\\Users\\user\\Downloads\\output.docx");
}
private void browseButton_Click(object sender, EventArgs e)
{
var fsd = new FolderSelect.FolderSelectDialog();
fsd.Title = "Select folder to save document";
fsd.InitialDirectory = #"c:\";
if (fsd.ShowDialog(IntPtr.Zero))
{
testTXT.Text = fsd.FileName;
}
}
}
public class GeneratedClass
{
**trying to access testTXT right here, but can't.**
}
}
Any help would be greatly appreciated.
You could do this (see other answers), but you really shouldn't.
Nobody but the containing form has to know about the textboxes in it. Who knows, they might disappear, have their name changed, etc. And your GeneratedClass could become a utility class used by lots of forms.
The appropriate way of doing this, is to pass whatever you need from your textbox to your class, like so:
private void testButton_Click(object sender, EventArgs e)
{
GeneratedClass gc = new GeneratedClass();
gc.CreatePackage(this.testTxt.Text);
}
public class GeneratedClass
{
public void CreatePackage(string name) { // DoStuff! }
}
This is because you have your TextBox type defined in Form1 class as private member. Thus can't be access with another class instance
Your question has little to do with C#, more to do with Object Oriented Concepts.
Instance of TextBox has to be given to 'GeneratedClass' somehow.
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void testButton_Click(object sender, EventArgs e)
{
GeneratedClass gc = new GeneratedClass(testTXT);
gc.DoSomething();
gc.CreatePackage("C:\\Users\\user\\Downloads\\output.docx");
}
private void browseButton_Click(object sender, EventArgs e)
{
var fsd = new FolderSelect.FolderSelectDialog();
fsd.Title = "Select folder to save document";
fsd.InitialDirectory = #"c:\";
if (fsd.ShowDialog(IntPtr.Zero))
{
testTXT.Text = fsd.FileName;
}
}
}
public class GeneratedClass
{
TextBox _txt;
public GeneratedClass(TextBox txt)
{
_txt= txt;
}
public void DoSomething()
{
txt.Text = "Changed the text";
}
}
}
You must make testTXT public.
See Protection level (Modifiers) of controls change automaticlly in .Net.
And access to TextBox as
public class GeneratedClass
{
GeneratedClass(Form1 form)
{
form.testTXT.Text = "1";
}
}
My program has a main form where I keep a repository of values from other sub forms. For some reason the sub form is giving me an error:
an object reference is required for the non-static field
This is my main form:
public partial class frm_SystemLog : Form
{
public frm_SystemLog()
{
InitializeComponent();
}
public string TextBoxValue
{
// suppose to get value from other forms
get { return this.textBox1.Text; }
set { textBox1.Text = value; }
}
private void frm_SystemLog_Load(object sender, EventArgs e)
{
Log frm_LoginMenu = new Log();
frm_LoginMenu.ShowDialog();
}
}
This is my sub form:
public partial class Log : Form
{
public Log()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
// this is where the error happens
frm_SystemLog.TextBoxValue = "SomeValue";
this.Close();
}
}
you should create a property in your log form then set its value when you are accessing it
//in log form
public String MyValue{get;set;}
then in properties of your button2 of log form choose dialogresult and set it to ok
then in your button2 click event
private void button2_Click(object sender, EventArgs e)
{
MyValue = "SomeValue";
//no need to close ,dialogresult will do it...
}
then in your frm_SystemLog form do this
private void frm_SystemLog_Load(object sender, EventArgs e)
{
Log frm_LoginMenu = new Log();
frm_LoginMenu.ShowDialog();
if(frm_LoginMenu.ShowDialog() == DialogResult.OK)
{
this.TextBoxValue = frm_LoginMenu.MyValue;
}
}
this should solve your problem.
frm_SystemLog.TextBoxValue isn't accessible from button2_Click, because it's in a different class.
Currently you're trying to reference an object on your parent form class, not an instance of your class. In that case, the only objects you can reference are static ones, hence the error you're getting.
You need an actual reference to the instance of your parent form. Change your Log class as follows:
public partial class Log : Form
{
private frm_SystemLog parentForm;
public Log(frm_SystemLog parentForm)
{
InitializeComponent();
this.parentForm = parentForm;
}
...
...
Then instantiate your sub form using:
Log frm_LoginMenu = new Log(this);
Read "Understanding Classes, Methods, and Properties in C#" for more information, in particular:
There are two kinds of methods in C#. They are:
Instance Method
Static Method
Instance Methods are methods declared outside the main method and can be accessed only by creating an object of the corresponding class.
Class methods also are declared outside the main method but can be accessed without creating an object of the class. They should be declared with the keyword static and can be accessed using the classname.methodname syntax.
I am writing a windows form application in c#. I changed my design to have menus. I have base class and several child class for each menu item. My problem is in my base class i am accessing a GUI element and storing its value in a public variable. now i want to access this from my child class.
public partial class x: Form
{
# calling this public method from child class to to get the variable value
public string Getlogpath()
{
Console.WriteLine(this.logpath);
return logsdirectory.Text;
}
private void reportFromLogsToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 child1 = new Form2();
this.LayoutMdi(System.Windows.Forms.MdiLayout.Cascade);
child1.Show();
}
public void browse_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.SelectedPath = (#"\\comprion02\ots\SHARED\T\COMPRION SIMfony\Log-Files");
fbd.ShowDialog();
logsdirectory.Text = fbd.SelectedPath;
logpath = logsdirectory.Text;
# this print i get value i need
Console.WriteLine(logpath);
}
}
#child form class
public partial class Form2 : Form
{
private void button1_Click(object sender, EventArgs e)
{
string data;
x obj = new x();
data = obj.Getlogpath();
#got nothing for this print
Console.WriteLine(x);
}
}
could someone help me with this.
Use this Console.WriteLine(Form.Getlogpath()); instead of Console.WriteLine(x);
Or create object of your Form class instead of X class:
Form obj = new Form();
Console.WriteLine(obj.Getlogpath());
Why don't you use the keyword protected instead of private or public. See more here - http://msdn.microsoft.com/en-us/library/wxh6fsc7(v=vs.71).aspx
I have this problem, i've set a value to a property from shall we say Form1, then get that value in Form2 but it return null.
sample code.
//Sample.cs
public class Sample
{
private string exchange;
public Sample()
{
}
public string Exchange
{
get { return exchange; }
set { exchange = value; }
}
}
//From Form1 set value
private void setBtn_Click_1(object sender, EventArgs e)
{
Sample testing = new Sample();
testing.Exchange = exchange.Text;
}
//From Form2 get value
private void getBtn_Click_1(object sender, EventArgs e)
{
Sample testing2 = new Sample();
string exchange2 = testing2.Exchange;
}
Here's the problem, exchange2 have a value of null, i know its because i declared a new instance, please tell me how to get the value using Form2 that have been set in Form1.
Thanks in advance guys!
It is OK return null because you each time create a new object
Sample testing2 = new Sample();
declare the public property in Form2 class
class Form2
{
public Sample MySample {get; set;}
}
private void setBtn_Click_1(object sender, EventArgs e)
{
Sample testing = new Sample();
Form2 form2 = new Form2();
form2.MySample = testing;
form2.Show();
}
If you want to use classes and properties in this way make exchange field static so it will be shared among all instances of your class. Static fields are class related and not instances related and in your case from Form1 and Form2 you are creating different instances of class.
Following are few posibilites:
1) Delcare the property static:
public static string Exchange{get;set;}
2) Pass the object created in Form1 in some way to Form2: