Access object from another button click event [duplicate] - c#

This question already has answers here:
The name 'str' does not exist in the current context
(2 answers)
Use a variable from another method in C#
(2 answers)
Closed 5 years ago.
I'm fairly new to C# so this might be pretty simple actually though I have spent a couple hours searching without a solution.
I'm working with windows form and I am trying to access an object from another button-click event. The error I'm getting is "The name 'object' does not exist in the current context" when trying to access object in Button2_Click.
public void Button1_Click(object sender, EventArgs e)
{
// Prefilled with a persons info
MyClass object = new MyClass();
}
public void Button2_Click(object sender, EventArgs e)
{
// Access object
string name = object.Name;
}
So my question is how do I access an object created in another "Button_Click"?

A couple of issues exists.
You can't use object as variable name. (object is a reserved keyword)
You can't access a internal variable, within another event.
To solve your issue, you would scope the variable when your initial object is created.
public class Example
{
// Variable declared as a class global.
private readonly Sample sample;
// Constructor to build our sample.
public Example() => sample = new Sample();
// Button writing a property from sample.
protected void btnSend(object sender, EventArgs e) => Console.WriteLine(sample.SomeProperty);
}
So the object is in the upper portion of your class, when you build Example, a sample is always created. So as you utilize Sample within your Example class, it will be correctly scoped.
I also don't understand why you have to click one button, to populate this object, so I altered to have the object built once Example is created.

The scope of the object should be class level in order to be used by other methods in the same class:
private MyClass _myClassObject; // class level object. Remember "object" is reserved keyword that is why renamed it to "_myClassObject"
public void Button1_Click(object sender, EventArgs e)
{
// Prefilled with a persons info
_myClassObject = new MyClass();
}
public void Button2_Click(object sender, EventArgs e)
{
// Access object
string name = _myClassObject.Name;
}

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

CS7036 C# WinForm There is no argument given that corresponds to the required formal parameter [duplicate]

This question already has answers here:
There is no argument given that corresponds to the required formal parameter - .NET Error
(6 answers)
Closed 1 year ago.
I have the following error
CS7036 C# There is no argument given that corresponds to the required
formal parameter 'dt' 'Cadbury_Chocolate.Cadbury_Chocolate(Cart)'
Chocolate Brand List.cs
private void pictureBox1_Click(object sender, EventArgs e)
{
new Cadbury_Chocolate().Show();
}
Cadbury_Chocolate.cs
public partial class Cadbury_Chocolate : Form
{
Cart dtGrid;
public Cadbury_Chocolate(Cart dt)
{
InitializeComponent();
this.dtGrid = dt;
}
private void button1_Click(object sender, EventArgs e)
{
dtGrid.dataGridView1.Rows.Add(label1,label2);
}
}
Cart.cs
public partial class Cart : Form
{
public Cart()
{
InitializeComponent();
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
}
How can I solve it?
You are calling the class constructor Cadbury_Chocolate() in this line new Cadbury_Chocolate().Show(); but you have only defined a constructor that take one argument of type Cart which is Cadbury_Chocolate(Cart dt).
Consider either:
Adding/defining another constructor with no parameters Cadbury_Chocolate().
Adjust your class instantiation by providing a Cart parameter to the already defined constructor Cadbury_Chocolate(Cart dt).
You may want to read about using constructors
The mentioned error was already answered here: There is no argument given that corresponds to the required formal parameter - .NET Error
You're not providing the required argument "Cart dt".
private void pictureBox1_Click(object sender, EventArgs e)
{
new Cadbury_Chocolate(cart).Show();
}
Replace "cart" with your cart reference.

Could .net Timer event handler modify a non-static variable [duplicate]

This question already has answers here:
CS0120: An object reference is required for the nonstatic field, method, or property 'foo'
(9 answers)
Closed 4 years ago.
c# Timer (System.Timers.Timer) is used to periodically trigger an event within windows form application. I would like to call function (for example logger() function) within the even handler. logger() is not a static method.
The function assigned to ElapsedEventHandler is a static function and therefore cannot call non-static methods.
Code example:
public partial class MainForm : Form {
//...
private MyClass myClass;
//...
}
private void SomeButton_Click(object sender, EventArgs e) {
//...
System.Timers.Timer t = new System.Timers.Timer(5000);
t.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
t.Enabled = true;
//...
}
static void OnTimerElapsed(object sender, ElapsedEventArgs e) {
//...
// here call myClass.doSomething();
//...
}
How would be the correct way to go about this task? I do know that static variables/methods are not possible to be used within the OnTimerElapsed() - that is clear. I mainly ask to check whether there is another way of calling OnTimerElapsed(), maybe a non-static method or another timer type or handler method? Or if there is a way to pass the instance of myClass to the OnTimerElapsed()
Edit: it would be preferable to keep the myClass non-static, that is why this question.
you cannot access non-static i.e. instance field with in static function , that is reason its not working.
If you want to access instance field with in static function then you need instance of object and then you can access that instance field.
Or make field static then you can access field
if you make
static var someNonStaticVariable = 1000; // for example
it will work but then you need locking around that variable or Interlocked (userful if you just want to perform increment/decrement or excahnge i.e. for numeric operation).

How do I change the value of form controls without triggering any event?

I want to change the value that is assign to control of a form in c# (visual studio 2010), while the form is loaded.
I want my form should display to the end user, but at the same time as I get the data from server, I want it to reflect the same data onto the controls. (without any using timer, thread or any event).
Example : textBox1.text ="abc";
if server is sending "xyz" than while form is already loaded testbox's value should automatically change to xyz.
without any click or any kind of event.
You have to look at how Properties in c# work:
If we decompile a simple class on sharplab.io
public class C {
public int foo
{get;set;}
}
You will see that the compile will always generate backing fields and a getter and setter method.
So if you don't want to trigger an event you will have to bypass these methods as most likely the event will be triggered in there.
This should be doable with an reflection which is normally pretty easy to do.
BUT Textbox doesn't seem to have a backing field which is easily accessible for its Text-Property. Most likely it is set by its private StringSource field. Which is from the internal type StringSource. So first we have to get the type. Get a reference to the constructor then call this and set the private field.
This is how far i've come:
private int number = 0;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
number++;
this.textBox1.Text = number.ToString();
}
private void button2_Click(object sender, EventArgs e)
{
number++;
Type cTorType = typeof(string[]);
string[] cTorParams = new string[] { number.ToString() };
Type type = this.textBox1.GetType().GetRuntimeFields().ElementAt(11).FieldType;
ConstructorInfo ctor = type.GetConstructor(new[] { cTorType });
object stringSourceInstance = ctor.Invoke(new[] { cTorParams });
this.textBox1.GetType().GetRuntimeFields().ElementAt(11).SetValue(this.textBox1, stringSourceInstance);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("Changed!");
}
I'd recommend digging a bit more into reflection and see what you can find in the TextBox class by using typeof(TextBox).GetFields / .GetProperties because somewhere there must be a field or property which you can change to bypass your setter method triggering the event.
Hope this helps.

public int loses value after an action is completed

My int, which is declared in a seperate class in dataStorage.cs, loses its value after this action is done:
private void button1_Click(object sender, EventArgs e)
{
dataStore dataStore = new dataStore();
dataStore.position = Convert.ToInt32(numericUpDown1.Value);
} // <= right here the value is reset to 0
what I am trying to do is, passing values between forms. but when the other form starts its process my dataStorage.position loses its value and resets to "0".
How can I properly pass values between forms?
This is because you are creating a local storage variable, which immediately goes out of scope.
Declare it as part of the form class:
public class MyForm : Form
{
public dataStore _dataStore = new dataStore();
public MyForm() { }
private void button1_click(Object sender, EventArgs e)
{
_dataStore.position = Convert.ToInt32(numericUpDown1.Value);
}
}
You haven't done anything with dataStore. It sounds like you're wanting to set the value of position for an instance of dataStorage that you're not actually using. You need to set the instance of dataStorage to the instance you create in that button for it to retain its value.
This behavior is actually expected.
When you instantiate an object, it has scope only in the context it was created in.
private void button1_Click(object sender, EventArgs e)
{
dataStore dataStore = new dataStore();
dataStore.position = Convert.ToInt32(numericUpDown1.Value);
} // When this function returns, dataStore no longer exists!
In this case, your dataStore object only exists inside of the button click handler.
What you want to do is declare the DataStore as a private member of your class, and then assign the value in the click handler.
private dataStore dataStore = new dataStore();
private void button1_Click(object sender, EventArgs e)
{
dataStore.position = Convert.ToInt32(numericUpDown1.Value);
} // <= right here the value is reset to 0
Also the actual class name in C# should have a capitalized letter for each word (PascalCase), not lowercase first letter followed by capitalized for remaining words (camelCase):
class DataStore { }
...
private DataStore dataStore = new DataStore();
You don't persist the value in any lasting location. Here's an explanation of what you're doing:
private void button1_Click(object sender, EventArgs e)
{
// You've called a function, in this case a click handler
// Here you create an instance of `dataStore`
// This instance exists *only* within the scope of this function
dataStore dataStore = new dataStore();
// Here you set a value on that instance
dataStore.position = Convert.ToInt32(numericUpDown1.Value);
}
// Now that the function has ended, any variables which were declared
// within the scope of the function are now out of scope, and removed
// from memory.
What's not clear from this code is how the value should be persisted. There are many options:
Declare the value as static, in which case you don't need to create a new instance. A static value would be available anywhere in the code.
Store the value in some persistence medium, such as a database. Basically you'd commit your dataStore object to persistence and retrieve it somewhere else.
Pass your dataStore instance as a method argument to whatever you're calling next.
Declare dataStore as a class-level member for this form and reference it in the other method.
It's likely (but, again, we can't know for sure from this code) that you want the fourth option. Which would look something like this on your form:
public class YourForm : Form
{
private dataStore dataStore = new dataStore();
private void button1_Click(object sender, EventArgs e)
{
dataStore.position = Convert.ToInt32(numericUpDown1.Value);
}
private void YourOtherMethod()
{
// dataStore.position will have a value after the button
// click handler is executed
}
}
The main point here is to think in terms of object instances. Think of a class as a "blueprint" for an object. When you create a new object, you're building an instance based on that blueprint. That instance is now unique in the system, and if you need to access it elsewhere in the code then that instance needs to be passed around the system in some way.

Categories

Resources