How do I expose a control's property publicly? - c#

I want to expose the Text property of a textbox on Form1 to Form2 so Form2 can set the text in the textbox on Form1. I've read how to do it but it doesn't work so I must be doing something wrong.
Here's the code for Form1 including the declaration of the public property (TextInputText is the property, txtInput is the textbox):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public string TextInputText
{
get => txtInput.Text;
set => txtInput.Text = value;
}
public Form1()
{
InitializeComponent();
}
private void txtInput_KeyDown(object sender, KeyEventArgs e)
{
// If enter is pressed clear the textbox, but update() the history first
if (e.KeyCode == Keys.Enter)
{
TextHistory.Update(txtInput.Text);
txtInput.Text = "";
}
}
private void HistoryButton_Click(object sender, EventArgs e)
{
Form2 HistoryForm = new Form2();
HistoryForm.Show();
}
}
}
The problem is Form2 still can't see the property, or I don't know how to access it, what am I doing wrong?

Either inject Form2 with a reference to Form1 when you create it:
private void HistoryButton_Click(object sender, EventArgs e)
{
Form2 HistoryForm = new Form2(this);
HistoryForm.Show();
}
This requires you to define a custom constructor in Form2 that accepts a Form1 reference. You can then use this reference to access the property:
private readonly Form1 _form1;
public Form2(Form1 form1)
{
InitializeComponent();
_form1 = form1;
string text = _form1.TextInputText;
}
Another approach is to use the Application.OpenForms property to get a reference to Form1 in Form2:
var form1 = Application.OpenForms.OfType<Form1>().FirstOrDefault();
string text = form1.TextInputText;

You do not give Form2 a reference to the Form1 instance:
Form2 HistoryForm = new Form2();
How could you access a Instance Function, Property or Value, without a Instance? A static property would not make sense. So the most likely option is to give Form2 a constructor that takes a Form1 reference as Argument. Store that reference somewhere in Form2. Then call the constructor like this:
Form2 HistoryForm = new Form2(this);

Related

System.StackOverflowException when switching between forms

I am trying to create a menu for a game I' m developing. This is the source code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Racing_Manager
{
public partial class Form1 : Form
{
Form1 form1 = new Form1();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
//Exit Button
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
//Help Button
private void Help_Click(object sender, EventArgs e)
{
}
//Play Button
private void Play_Click(object sender, EventArgs e)
{
Hide();
Form2 secondMenu = new Form2();
secondMenu.Show();
}
}
}
Then I have:
namespace Racing_Manager
{
public partial class Form2 : Form
{
public Form2 form2 = new Form2();
public Form2()
{
InitializeComponent();
}
//Back Button
private void button2_Click(object sender, EventArgs e)
{
Hide();
Form1 form1 = new Form1();
form1.Show();
}
}
}
When I run this, it gives a System.StackOverflowException (I know, quite appropriate) on this line:
Form1 form1 = new Form1();
What am I doing wrong? How do I fix it? Anything I can do to improve the code quality?
Your problem is in the first lines:
public partial class Form1 : Form
{
Form1 form1 = new Form1();
What should this line do?
When you create an instance of Form1 it's members are initialized. Here you declared a member form1 that is initialized by creating a new instance of Form1.
When you create an instance of Form1 it's members are initialized. Here you declared a member form1 that is initialized by creating a new instance of Form1.
When you create an instance of Form1 it's members are initialized. Here you declared a member form1 that is initialized by creating a new instance of Form1.
When you create an instance of Form1 it's members are initialized. Here you declared a member form1 that is initialized by creating a new instance of Form1.
When you create an instance of Form1 it's members are initialized. Here you declared a member form1 that is initialized by CREATING A NEW INSTANCE OF Form1.
StackOverflowException
because you recursivly call the constructor of Form1 and so your call stack eventually runs full.
The same goes for Form2.
Conclusion: remove this line from your Form1 class (and the one from Form2), you don't need it anyway.
It's the very first line that's wrong:
public partial class Form1 : Form {
Form1 form1 = new Form1(); // <- this one
You're creating Form1 instance, but Form1 should initialize Form1 form1 field, which in turn creates Form1 instance with its own Form1 form1 to be initialized...
You have a property Form1 inside your Form1 class. It cause an infinite loop.
So you should change :
public partial class Form1 : Form
{
Form1 form1 = new Form1();
public Form1()
{
InitializeComponent();
}...
to
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}...
As the other answer state, Form1 and Form2 both create an instance of themselves when a new instance is constructed. It looks like you want a singleton. To achieve this change your code like so
//From
public Form1 = new Form1()
//To
public static Form1 = new Form1();
This will create an instance of the Form as soon as the Form1 class is referenced for the first time. So Form1.Form1 would automatically create a single instance.

Get data from one form to another form in C# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Respected Users,
i am trying to pass a value one Form2 to Form1, first of all in Form1 upon TextBox if i press Escape key then it will move me to Form2, now i want when i enter Value in Form2 TextBox and press the button then control move to back to Form1 and close the Form2 and show the value of Form2.TextBox into Form1.TextBox further i will show this value in MessageBox in Form1 by pressing Button, kindly guide me in easiest way i will be very thank full.
here is the code which i was using
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 twoFormsDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
Form2 form2 = new Form2();
form2.ShowDialog();
this.Close();
}
}
private void Form1_Load(object sender, EventArgs e)
{
Form1 form1 = new Form1();
textBox1.Text = Form2.SetValueForText;
form1.Refresh();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(textBox1.Text);
}
}
}
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 twoFormsDemo
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public static string SetValueForText = "";
private void button1_Click(object sender, EventArgs e)
{
SetValueForText = textBox1.Text;
Form2 form2 = new Form2();
form2.SendToBack();
this.Close();
}
}
}
You have two options for that:
Use a static class with a property to store the value in
Use events
I recommend the second way if you're not trying to access this value anywhere else.
Create an event with custom EventArgs that allow you to store a string inside them in your Form2 and make sure to raise it whenever you need to. You can subscribe this event in Form1 at the point you create the instance of Form2. Then you can work with the string value in your event handler.
You're not far off...
Change Form2 by setting DialogResult. This will dismiss it and return execution to Form1 at the ShowDialog point. Your field does not need to be static, however:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public string SetValueForText = "";
private void button1_Click(object sender, EventArgs e)
{
SetValueForText = textBox1.Text;
this.DialogResult = DialogResult.OK;
}
}
Now in Form1, use your instance of Form2 to get the value when "OK" is sent back:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
Form2 form2 = new Form2();
if (form2.ShowDialog() == DialogResult.OK)
{
textBox1.Text = form2.SetValueForText;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(textBox1.Text);
}
}
*Get rid of that code in your Load() event!
You need to think Form as a dumb UI layer. There should be lower layer that create these Forms and works with them. Look where instance of your Form is created (for inspiration). Look at MVC and MVVM pattern for more information.

Update textbox from a different class

I'm relatively new to C# and come a bit stuck.
I've got a Rich Textbox on a form, and I would like to update this from a different class to the Form itself.
I first tried
Form1.outputTextbox.AppendText(string);
but the text box was not accessible, made sense. So instead I tried to make a function. On Form1 I created the function
public void updateTextBox(string new_text)
{
outputTextBox.AppendText(new_text);
}
and in the class I used.
Form1.updateTextBox("apple");
The problem I'm having is the only way my class can see the function is if I make it the function static, but when I do that get an error "An object reference is required for the nonstatic field, method, or property 'member'"
Am I close or going to wrong way about this completely? Any help would be appricated.
Alternatively, you can do something like the following. This takes advantage of custom arguments and events.
namespace WindowsFormsApplication3
{
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;
public partial class Form1 : Form
{
TextBox textBox;
SomeClass someClass;
public Form1()
{
InitializeComponent();
Initialize();
BindComponents();
}
private void BindComponents()
{
//EventHandlers
this.Load += new EventHandler(Form1_Load);
this.someClass.TextUpdatedEvent += new EventHandler(someClass_TextUpdatedEvent);
}
void someClass_TextUpdatedEvent(object sender, EventArgs e)
{
this.textBox.Text = (e as FormArgs).Text;
}
private void Initialize()
{
this.textBox = new TextBox();
this.someClass = new SomeClass();
}
void Form1_Load(object sender, EventArgs e)
{
this.Controls.Add(textBox);
}
}
public class SomeClass
{
public event EventHandler TextUpdatedEvent = delegate { };
public void UpdateText(string text)
{
if (TextUpdatedEvent != null)
{
TextUpdatedEvent(this, new FormArgs() { Text = text });
}
}
}
public class FormArgs : EventArgs
{
public string Text { get; set; }
}
}
If you do it this way, you can update the form text like this:
someClass.UpdateText("changing the text on the form");
You are trying to access the function from the class instead of the object.
Use
Form1 myForm = new Form1();
...
myForm.updateTextBox("whatever");
Also be aware of thread issues here. What triggers the outside code? Is it another ui action, then all is well. Does it come from another thread, then you´ll have to handle this.
Pass Form1 instance to the other class via constructor or property. Then you can access outputTextbox from the other class.
public class OtherClass
{
private Form1 form1;
public OtherClass(Form1 form1)
{
this.form1 = form1;
}
private void ChangeText()
{
form1.outputTextBox.AppendText("hello world");
}
}
Instantiate OtherClass from Form1.cs and pass its instance.
In Form1.cs:
OtherClass obj = new OtherClass(this);
I know it is very late, but maybe someone need the solution...
you can access to all controller from another form without create object by pass it as parameter to constructor...
for Example
public partial class Form2 : Form
{
MainForm mainForm;
public Form2(MainForm mainForm)
{
InitializeComponent();
this.mainForm = mainForm;
txtRecive00.TextChanged += new EventHandler(txtRecive8changed);
}
void txtRecive8changed(object sender, EventArgs e)
{
mainForm.txtRecive1.Text += txtRecive00.Text;
}
in my case I can update the text in mainForm.txtRecive1.Text from Form2...
and in MineForm we creat object from Form2 like that:
Form2 f2 = new FormMeasure(this);
for more Info show this short video https://www.youtube.com/watch?v=CdH8z_JNi_U

How to get checkstate and checkbox.text from different Class

i need your help again.. i doing this program that if the checkbox from Form2.cs is checked then i will clicked a button to show another WindowsForm(another Form.cs) that has a listbox that will show a the text from that checkbox. here is my work on the other form.cs
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 WindowsFormsApplication7
{
public partial class computationOfDineIn : Form
{
Form2 form2 = new Form2();
public computationOfDineIn()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (form2.checkBox1.Checked)
{
listBox1.Items.Add(form2.checkBox1.Text.ToString());
}
}
}
}
i change the modifier of the checkbox in Form2.cs to Public so i can use it in another form. but it doesn't work, am I missing somehthing? please somebody tell me. (Q. how can i make it appear in the listbox from another form when the conditions is met?) I knmow this is a silly question but thank you in advance!!! :D
update: code on where Form2 is shown.
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 WindowsFormsApplication7
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
}
private void button2_Click(object sender, EventArgs e)
{
Form3 form3 = new Form3();
form3.Show();
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
It seems you're creating new instance of Form2 inside computationOfDineIn. You should use the same instance of form2 which you show to user.
And making the UI elements public is not the recommended way. IMO you've to create a property which says whether the checkbox is checked or not.
You need to save the form2 instance somewhere and somehow you need to pass the instance to computationOfDineIn form then check the property in that instance.
One way is to pass it through constructor.
public partial class computationOfDineIn : Form
{
Form2 form2 = null;
public computationOfDineIn(Form2 form2)//pass the form2 you created in button click
{
this.form2 = form2;
InitializeComponent();
}
}

How to get variable from form1 to form2 with { get; set;}?

All.
I'm newbie in C#. I know this is very popular question. But I didn't understand. I know there is a mistake, but where?
For example - first part of code Form1 include private variable test, I need to get the value of this variable in the Form2. Where is the error?
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 WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string test = "test this point";
Form2 dlg = new Form2();
dlg.test = test;
dlg.Show();
}
}
}
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 WindowsFormsApplication1
{
public partial class Form2 : Form
{
public string test { get; set; }
public Form2()
{
InitializeComponent();
label1.Text = test;
}
}
}
In your Form2 you are using a public property, because it is public you can assign it via the object in form1. For example:
private void button1_Click(object sender, EventArgs e)
{
Form2 dlg = new Form2();
dlg.test = "test this point";
dlg.Show();
}
There are a couple of ways to use this in form 2, if you just want it to set the text property of the label only, this would be the best:
public partial class Form2 : Form
{
public string test
{
get { return label1.Text; }
set { label1.Text = value ;}
}
public Form2()
{
InitializeComponent();
}
}
Within the setter of the property you could also call a function if required.
You are right, this type of question has been asked many times, slightly different versions... Here's some answers I've provided in the past
This might be closest for what you are looking for
One answer getting a value via a method calls
Another, with step-by-step to create two forms and getting values to/from the other with function or Getter(setter)
You're not using the string test anywhere within your method. Try this:
private void button1_Click(object sender, EventArgs e)
{
Form2 dlg = new Form2();
dlg.Test = "test this point";
dlg.Show();
}
See how you're assigning the value to the property Test on the Form2 object dlg.
Note: I used a captial for the property Test since that's the general consensus on style for property names.
test is a property available for Form2 (better case it to Test) while the string test is just scoped for the click event of Form1. It has no relation to the property unless you assign it.
Form2 dlg = new Form2();
dlg.test = test; // this will assign it
dlg.Show();
Now Form2 property has got the value which will be used to display the same in the Label

Categories