Search code examples
c#winformsinstance-variables

How do I pass variables between methods in C#?


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;
        }
    }
}

Solution

  • 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:

    1. user enters some text into textbox1
    2. user clicks on button1, this will save the current value from textbox1
    3. 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

    1. 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; }
      
    2. 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.

    3. 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.