c# accessing string from method1 in method2, after method1's execution - c#

I'm working on a form with one textbox, one button, one combobox and a couple of other textboxes.
So, I want this winforms program to work as follows:
1) you fill in a database index value in textbox1 (example: 22222)
2) you click the button. This button goes to the database, looks up the value in textbox1 and eventually creates a string based on what the database returns. (example: returned value = super; string value = 5)
3) After you've clicked the button, you should be able to fill in the other textboxes depending on the SelectedIndex of the combobox. The values filled in in the combobox are completely dependant on the value of the string generated by button1. (example: combobox1 selectedindex = 1: textbox2.text = S; combobox selectedIndex = 2: textbox3.text = U)
So, basically, button1 must first be executed before combobox1 can even begin to execute itself. Also note that there are (at least) two methods used here: a void for button1_click and a void for combobox1_selectedindexchanged.
The two first parts are done. What I'm having trouble with is accessing the string generated by button1, which is only accessible after its execution, and using it in combobox1's method.
Is this possible?

create a property on your Form class which is populated once the button 1 is clicked with the value from your textbox.
then simply use it whenever and however you need.
example code :
public partial class Form1 : Form
{
public string Value;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Value = textBox1.Text;
textBox2.Text = this.Value;
}
}

Thanks for the help!
I was eventually able to do it like this, to truly access the variable inside the scope of method2, while it was created in method1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string output = "test";
File.WriteAllText(#"C:\output.txt", output)
}
private void combobox1_SelectedItemChanged
{
string output = File.ReadAllText(#"C:\output.txt")
// do something with this string
}
}

Related

How do I pass variables between methods in C#? [duplicate]

This question already has answers here:
Use a variable from another method in C#
(2 answers)
Closed 2 years ago.
I am trying to build a program, but I realized I can't access a certain variable because it's created in another method.
How do I transfer a variable to another method?
This is an example of what I'm trying to do:
namespace Example
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string text = textBox1.Text;
}
private void label1_Click(object sender, EventArgs e)
{
// Get the "text" variable and use it
label1.Text = text;
}
}
}
Your example has a Form named Form1 that has a Button named button1, a TextBox named textbox1 and a Label named label1.
The scenario you are attempting is:
user enters some text into textbox1
user clicks on button1, this will save the current value from textbox1
user clicks on label1, this will display the value that was stored in the previous step
It is important to understand that in this scenario we are not trying to pass a value between 2 methods because the button click and the label click can occur independently of each other, so really this is like the memory store (M+) and memory recall (MR) buttons on calculator.
To achieve this storage you should create an instance variable (sometimes referred to as a member variable) on the Form1 class, this will be accessible to the other methods on the same instance of the Form1 class.
See Working with Instance and Local variables for a practical explanation
Create a field or a property to store the value, for your specific example either would work, however to become familiar with C# techniques I would recommend you start with a property, as that better encapsulates your scenario of storing the value for later use and later to potentially augment how and where the value is actually stored.
See What is the difference between a field and a property?
for a healthy discussion
Until you need to change the implementation, you can simply use an Auto-Property
public string StoredText { get; set; }
Now in the click event handler of button1 we can set the value of the StoredText property on the Form1 instance
private void button1_Click(object sender, EventArgs e)
{
this.StoredText = textBox1.Text;
}
set is a term we use for saving a value into a property in c#
Note the use of the this keyword, it is optional in this case, or can be inferred by the compliler, it indicates that we want to reference a member on the instance of the class, not a variable that might have the same name within the same method scope of the line of code that is executing.
Finally in the click event handler of label1 we can get the value that was previously stored in the StoredText property in the Form1 instance.
private void label1_Click(object sender, EventArgs e)
{
// Get the "StoredText" variable and use it
label1.Text = this.StoredText;
}
get is a term we use for accessing a value from a property in c#
this is not required, but can be helpful to understand that we are accessing a member that is outside of the current method scope.
Together this looks something like:
namespace Example
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>Saved value from see <see href="textBox1"/></summary>
public string StoredText { get; set; }
private void button1_Click(object sender, EventArgs e)
{
this.StoredText = textBox1.Text;
}
private void label1_Click(object sender, EventArgs e)
{
// Get the "StoredText" variable and use it
label1.Text = this.StoredText;
}
}
}
What you may not have noticed is that textBox1 and label1 are themselves infact instance variables that are initialized in a separate code file when InitializeComponent() is executed in the constructor.
For this reason you do not need to store the value at all and you could simply re-write the client event handler for button1 to write directly to label:
label1.Text = textBox1.Text;
It is possible to pass variables directly between methods without an intermediary store, this is a lesson for another day and will involve return statements and/or parameters on your methods.
In this scenario however, neither return or additional parameters on these methods cannot be used because these are event handlers that need a specific method signature to operate as expected.
You are almost there. It is a common practice in object-oriented programming to have private variables in a class, in order to share states. Add a variable in your class. It will be available in all methods and can be used to shared data between them (this is one approach of many):
namespace Example
{
public partial class Form1 : Form
{
private string inputText { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
inputText = textBox1.Text;
}
private void label1_Click(object sender, EventArgs e)
{
// Get the "text" variable and use it
label1.Text = inputText;
}
}
}

Passing Data back to First Form from Second Form in C#

I have two Forms. Say FormA, FormB.
From FormA i called FormB using
frmB.Show();
In FormB, i've two textboxes and a combobox controls.
Assume User enters some data in those two textboxes and selected an item from combobox in Form2 and clicked an OK button.
After the click i want those textboxes user entered values, combobox selected item value back to FormA.
How can i achieve this using C#.
I approached the simple way .. little embellishments..
create public variables in your form class i.e.
public string passVariable1 = "";
if you have text boxes go to properties, then click on the lightning bolt and double click on the empty TextChanged eventhandler. This will create a code snippet in the code begind that gets executed when the content of the textbox changed .. in this code block assign the content of the text box to your corresponding public variable.
i.e. my public variable was
public string issue = "";
private void txtIssue_TextChanged(object sender, EventArgs e)
{
issue = txtIssue.Text;
}
Add a button and create a click event for this button (simply double click on the button in the design pane). In the click event code block set the dilog result to ok and hide the
this.DialogResult = DialogResult.OK;
this.Hide();
In the parent window code check on the dialog result and grab the form data from the child form's public variables
if (f.ShowDialog() == DialogResult.OK)
{
string b = f.issue;
string e = f.year;
string f = f.month;
};
In the scenario that you are describing I would probably call frmB.ShowDialog() rather than frmB.Show().
// Inside FormA open frmB as a modal dialog waiting for
// OK or Cancel result using the following statement
if (frmB.ShowDialog() == DialogResult.OK)
{
// Retrieve selected values from frmB here (while frmB is still not disposed)
}
The benefits of ShowDialog() are that you:
Get the return value from the form easily allowing you to determine that OK (rather than cancel) was clicked to close it.
The form is not immediately disposed when closed thus allowing you to retrieve the values that you want.
By opening frmB as a modal dialog you avoid having to check for the complexities that may occur if your user starts interacting with formA while frmB is open.
NOTE: When designing frmB you have to set the DialogResult property of the OK button-control to DialogResult.OK in order for the form to return the correct DialogResult when this button is pressed (alternatively can also set this.DialogResult in the OK button's Click event handler)
Or you could pass an object from FormA to FormB and bind its properties to the controls in FormB. If you want FormA to be notified when you click OK button you could declare an event in your data container class, subscribe to it in FormA and fire it from FormB.
Be DataContainer some class you define
public class DataContainer
{
public event EventHandler AcceptedChanges;
protected virtual void OnAcceptedChanges()
{
if ((this.AcceptedChanges != null))
{
this.AcceptedChanges(this, EventArgs.Empty);
}
}
public void AcceptChanges()
{
this.OnAcceptedChanges();
}
public string Text1 { get; set; }
public string Text2 { get; set; }
}
in FormA:
private void button4_Click(object sender, EventArgs e)
{
DataContainer data = new DataContainer();
data.Text1 = "text1";
data.Text1 = "text2";
Form2 frm = new Form2();
frm.Data = new DataContainer();
data.AcceptedChanges += new EventHandler(data_AcceptedChanges);
frm.Show();
}
void data_AcceptedChanges(object sender, EventArgs e)
{
// your code here
}
and in FormB:
public DataContainer Data { get; set; }
private void Form2_Load(object sender, EventArgs e)
{
textBox1.DataBindings.Add(new Binding("Text", Data, "Text1"));
textBox2.DataBindings.Add(new Binding("Text", Data, "Text2"));
}
private void button1_Click(object sender, EventArgs e)
{
Data.AcceptChanges();
}
You should also implement INotifyPropertyChanging and INotifyPropertyChanged on DataContainer class to play nice with bindings.
You can create an EventHandler on FormB which FormA will subscribe to. Also, add a couple of public properties to FormB that represent that data that you want FormA to be able to use. Then, when FormB fires off the event, FormA will know to refresh his data.
Note: The key principle in this example is implementing an EventHandler (you can create your own event handler type) which notifies FormA when data is ready to be refreshed/viewed/etc. Hopefully, this example will allow you to see how you might implement an event handler for your particular situation.
Example:
FormA -
public partial class FormA : Form
{
//FormA has a private instance of FormB
private FormB formB = null;
public FormA()
{
InitializeComponent();
}
void formB_OnDataAvailable(object sender, EventArgs e)
{
//Event handler for when FormB fires off the event
this.label1.Text = string.Format("Text1: {0}\r\nText2: {1}",
formB.Text1, formB.Text2);
}
private void InitializeFormB()
{
this.formB = new FormB();
//FormA subscribes to FormB's event
formB.OnDataAvailable += new EventHandler(formB_OnDataAvailable);
}
private void button1_Click(object sender, EventArgs e)
{
this.InitializeFormB();
formB.Show();
}
}
FormB -
public partial class FormB : Form
{
//Event that fires when data is available
public event EventHandler OnDataAvailable;
//Properties that expose FormB's data
public string Text1 { get; private set; }
public string Text2 { get; private set; }
public FormB()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Set the exposed properties, then fire off the event.
this.Text1 = this.textBox1.Text;
this.Text2 = this.textBox2.Text;
if (OnDataAvailable != null)
OnDataAvailable(this, EventArgs.Empty);
}
}
A dirty, but also fastest solution is to make those controls public. This you can do by adding the word public in the Form2.Decisgner.cs file. If FormA has a member variable or local variable of FormB, you can access the control (say TextBox1) with:
frmB.TextBox1.Text
which is now accessible outside FormB too.
How about using events and delegates? See this http://colinmackay.scot/2005/04/22/passing-values-between-forms-in-net/
I was having this same issue and came up with an idea which is a bit different. In my scenario, I am making a flashcard program for my youngest two children and I wanted to be able to carry back the answer provided to the parent form (new child form for each new flashcard question so that the parent form can update how many are left, how many correct, how many incorrect, etc.) without having to add values to a database. Seems to be overkill for something that should be simple. What I did was to create a class with 3 of each variable type. I figured three of each type would be sufficient for most jobs.
This is an example of my new class:
namespace ClassNamespace
{
public class ValueHolder
{
public int intValue1 { get; set; }
public int intValue2 { get; set; }
public int intValue3 { get; set; }
public long longValue1 { get; set; }
.
.
.
}
}
I create a new ValueHolder (ValueHolder vh;) from parent form and pass it to the child form. In the child form I create a new ValueHolder and then set it equal to the ValueHolder object sent in the child form's class constructor. Now, when the enter key is pressed (answer given), I can set vh.intValue1 equal to this.answerBox.text;... well, I have to use int.tryparse(); but you get the idea. I then only need to reference vh.intValue1 from the parent form to get the value entered.
Parent form:
for (int i = 0; i < limit; i++)
{
ValueHolder vh = new ValueHolder();
ChildClass cc = new ChildClass(vh);
MessageBox.Show(vh.intValue1.ToString()); //to test that it works
}
and child form:
ValueHolder vh;
public ChildClass (ValueHolder vhIncoming)
{
vh = vhIncoming;
}
private void answerBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
vh.intValue1 = 1234;
}
}
This seems to be the simplest solution for my scenario. I know that this question is old, but wanted to add this option for anyone in a similar position. Just add the class to your project, add more of a type or more types to the class as needed, rinse repeat for future projects.
If its on the same page you should be able to read it directly from your controls as Textbox1.Text, Textbox2.Text, Combobox.SelectedValue (i guess)
But if its on different pages use Session variables like:
Session["date1"] = TextBox1.Text;
Session["date2"] = TextBox2.Text;
Session["comboValue"] = Combobox.SelectedValue;
and use them to populate your form
This would depend on how you normally design your applications.
You could work by using a event
driven system where you would create
events and delegates. Mentioned by #Dave81
Or you could create properties that
return the given/selected values so
that the parent can retrieve them
from the object (Wanted to say Dialog
but not sure about what your using).
Or you can follow #zmilojko and just
set them public, which is basically
the same as creating properties but
more to the dark side of coding
practices :D
All these would work but it all depends on how you like your applications to be structured.

Accessing Form's Control from Custom Control

I want to access the list box and add the item into it for my Custom control which is dynamically created on run time. I want to add the Item when I press the button place in the custom control, but it does not work. I have use the following code to work:
private void button1_Click(object sender, EventArgs e)
{
Form1 frm = new Form1();
frm.ABC = "HI";
}
the 'ABC' is the Public string on the form ie:
public string ABC
{
set { listBox1.Items.Add (value); }
}
the above string works fine when I use it form the Button on the form and it adds the value in the lsitbox but whent I use it form the custom control's button the text of the 'value' changes but it does not add the item in list box.I have also try it on tabel but does not help. I change the Modifires of the ListBox1 from Private to Public but it does not works. The above function works well in the form but cannot work from the custom control.
Thanks.
Expose an event ("ItemAdded" or whatever) in the child form that your main form can handle. Pass the data to any event subscribers through an EventArgs derived object. Now your mainform can update the UI as it please with no tight coupling between the two classes. One class should not know about the UI layout of another, it's a bad habit to get into (one that everyone seems to suggest when this question crops up).
What I think you should use is
this.ParentForm
So in your case it should be:
public string ABC
{
set { this.ParentForm.listBox1.Items.Add (value); }
}
The easiest way would be to pass the form down into your custom control as a parameter in the constructor that way you could access it from the custom control.
EX:
public class CustomControl
{
private Form1 _form;
public CustomControl(Form1 form)
{
_form = form;
}
private void button1_Click(object sender, EventArgs e)
{
_form.ABC = "HI";
}
}

Add to listview from another form

I am wondering how I can update my listview in form1 by entering data via textboxes in form2. My code works fine if i put all the text boxes on the same form etc.
I figured I needed some reference to the first form on 2nd but can't get it working.
Any tips for putting me in the right direction would be nice, also any tips for any better way of doing this.
This is the code I have so far:
Form1:
public partial class form1 : Form
{
public form1()
{
InitializeComponent();
}
public ListView MyListView
{
get
{
return taskList;
}
}
Form2:
public partial class form2 : Form
{
public form2()
{
InitializeComponent();
}
form1 f;
public add(form1 f)
{
this.f = f;
}
public void AddToList()
{
ListViewItem item1 = new ListViewItem(txtName.Text);
item1.SubItems.Add(txtEmail.Text);
item1.SubItems.Add(txtPhone.Text);
f.MyListView.Items.AddRange(new ListViewItem[] { item1 });
}
The most straight forward way of doing things would be to use events. You could add an event on form2 that would fire each time an item is added, and includes the text to be inserted (you have multiple pieces of information, so a custom data type would be appropriate). You can then add a handler method to form2 which adds the item to its ListView. You then tie the two together in the code that is creating the two forms, and life should be good.
So, to provide some code, First up is the data structure for the event:
public delegate void HandleItemAdded(object sender, ItemAddedEventArgs e);
public struct ItemAddedEventArgs : EventArgs
{
public string Name;
public string Email;
public string Phone;
public ItemAddedEventArgs(string name, string email, string phone)
{
Name = name;
Email = email;
Phone = phone;
}
}
Then we have the event code on form2
public event HandleItemAdded ItemAdded;
// .. some other stuff
public void RaiseItemAdded(ItemAddedEventArgs e)
{
if(ItemAdded != null)
ItemAdded(this,e);
}
// ... now for your AddToList
public void AddToList()
{
RaiseItemAdded(new ItemAddedEventArgs(txtName.Text,txtEmail.Text, txtPhone.Text);
}
And now we can add a handler in form1
public void HandleItemAdded(object sender, ItemAddedEventArgs e)
{
ListViewItem item1 = new ListViewItem(txtName.Text);
item1.SubItems.Add(txtEmail.Text);
item1.SubItems.Add(txtPhone.Text);
MyListView.Add(item1);
}
And last but not least we need to tie them together
//...not sure what your code looks like, but we'll assume we have instances of the two forms named form1Form and form2Form
form2Form.ItemAdded += form1Form.HandleItemAdded
the listview control should be private, instead add a public method to your form that contains the listview control, which receives the data you want to insert and inserts it into the listview.
If form2 is not created by and displayed by form1, you're not going to have a reference to call. In that case, things are going to get a bit more interesting from a communication standpoint. When that happens, you'll need to use an eventing model to get the information from one place to another.

How to change text in a textbox on another form in Visual C#?

In Visual C# when I click a button, I want to load another form. But before that form loads, I want to fill the textboxes with some text. I tried to put some commands to do this before showing the form, but I get an error saying the textbox is inaccessible due to its protection level.
How can I set the textbox in a form before I show it?
private void button2_Click(object sender, EventArgs e)
{
fixgame changeCards = new fixgame();
changeCards.p1c1val.text = "3";
changeCards.Show();
}
When you create the new form in the button click event handler, you instantiate a new form object and then call its show method.
Once you have the form object you can also call any other methods or properties that are present on that class, including a property that sets the value of the textbox.
So, the code below adds a property to the Form2 class that sets your textbox (where textbox1 is the name of your textbox). I prefer this method method over making the TextBox itself visible by modifying its access modifier because it gives you better encapsulation, ensuring you have control over how the textbox is used.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public string TextBoxValue
{
get { return textBox1.Text;}
set { textBox1.Text = value;}
}
}
And in the button click event of the first form you can just have code like:
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.TextBoxValue = "SomeValue";
form2.Show();
}
You can set "Modifiers" property of TextBox control to "Public"
Try this.. :)
Form1 f1 = (Form1)Application.OpenForms["Form1"];
TextBox tb = (TextBox)f1.Controls["TextBox1"];
tb.Text = "Value";
I know this was long time ago, but seems to be a pretty popular subject with many duplicate questions. Now I had a similar situation where I had a class that was called from other classes with many separate threads and I had to update one specific form from all these other threads. So creating a delegate event handler was the answer.
The solution that worked for me:
I created an event in the class I wanted to do the update on another form. (First of course I instantiated the form (called SubAsstToolTipWindow) in the class.)
Then I used this event (ToolTipShow) to create an event handler on the form I wanted to update the label on. Worked like a charm.
I used this description to devise my own code below in the class that does the update:
public static class SubAsstToolTip
{
private static SubAsstToolTipWindow ttip = new SubAsstToolTipWindow();
public delegate void ToolTipShowEventHandler();
public static event ToolTipShowEventHandler ToolTipShow;
public static void Show()
{
// This is a static boolean that I set here but is accessible from the form.
Vars.MyToolTipIsOn = true;
if (ToolTipShow != null)
{
ToolTipShow();
}
}
public static void Hide()
{
// This is a static boolean that I set here but is accessible from the form.
Vars.MyToolTipIsOn = false;
if (ToolTipShow != null)
{
ToolTipShow();
}
}
}
Then the code in my form that was updated:
public partial class SubAsstToolTipWindow : Form
{
public SubAsstToolTipWindow()
{
InitializeComponent();
// Right after initializing create the event handler that
// traps the event in the class
SubAsstToolTip.ToolTipShow += SubAsstToolTip_ToolTipShow;
}
private void SubAsstToolTip_ToolTipShow()
{
if (Vars.MyToolTipIsOn) // This boolean is a static one that I set in the other class.
{
// Call other private method on the form or do whatever
ShowToolTip(Vars.MyToolTipText, Vars.MyToolTipX, Vars.MyToolTipY);
}
else
{
HideToolTip();
}
}
I hope this helps many of you still running into the same situation.
In the designer code-behind file simply change the declaration of the text box from the default:
private System.Windows.Forms.TextBox textBox1;
to:
protected System.Windows.Forms.TextBox textBox1;
The protected keyword is a member access modifier. A protected member is accessible from within the class in which it is declared, and from within any class derived from the class that declared this member (for more info, see this link).
I also had the same doubt, So I searched on internet and found a good way to pass variable values in between forms in C#, It is simple that I expected. It is nothing, but to assign a variable in the first Form and you can access that variable from any form. I have created a video tutorial on 'How to pass values to a form'
Go to the below link to see the Video Tutorial.
Passing Textbox Text to another form in Visual C#
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
TextBox txt = (TextBox)frm.Controls.Find("p1c1val", true)[0];
txt.Text = "foo";
}

Categories

Resources