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).
Related
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.
I have COM server application which controls another application CANoe. I want to show a progress bar on Form2 of COM application. The value of progress bar should be updated in the EventHandler. The eventHandler calls a method of form2 which will update the value of progress bar. The EventHandler is in main form.
private void mCANoeProgProgressChangedInternal(string sysvarName, object Value) // in main Form
{
if (mCANoeMeasurement != null && mCANoeMeasurement.Running)
{
ProgressBarForm.Prog_progress(Value);
}
}
And in Form 2 -
public void Prog_progress(object value)
{
progressBarProg.Value = (int)value;
}
it is showing an error
"An object reference required for the non-static field, method or
property 'Form2.Prog_progress(object)'"
at - ProgressBarForm.Prog_progress(Value); in main form.
Please provide your comments.
In form 1 you need to execute Prog_progress method on an instance of Form2, not on the class (in a static way).
In Form1:
private ProgressBarForm _progressForm = new ProgressBarForm();
(...)
private void mCANoeProgProgressChangedInternal(string sysvarName, object Value) // in main Form
{
if (mCANoeMeasurement != null && mCANoeMeasurement.Running)
{
_progressForm.Prog_progress(Value);
}
}
Probably you are missing instantiating the Form2,
// This is for your parent Form1
public partial class Form1 : Form
{
private void mCANoeProgProgressChangedInternal(object sender, EventArgs e)
{
ProgressBarForm frm = new ProgressBarForm();
frm.DoSomething(value);
}
}
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;
}
Given this code....
public class CalibrationViewModel : ViewModelBase
{
private FileSystemWatcher fsw;
public CalibrationViewModel(Calibration calibration)
{
fsw = new FileSystemWatcher
{
Path = #"C:\Users\user\Desktop\Path\ToFile\Test_1234.txt",
Filter = #"Test_1234.txt",
NotifyFilter = NotifyFilters.LastWrite
};
fsw.Changed += (o, e) =>
{
var lastLine = File.ReadAllLines(e.FullPath).Last();
Dispatcher.BeginInvoke((Action<string>) WriteLineToSamplesCollection, lastLine); //line that cites error
};
}
private void WriteLineToSamplesCollection(string line)
{
// do some work
}
}
Why am I getting the error, 'Cannot access non-static method BeginInvoke in static context'?
I have looked at several other examples on SE and most cite trying to use a field before the object is created as if they were trying to use a non-static field in a static manner, but I don't understand what it is about my code that is invoking the same error.
Lastly, what can I do to fix this specific issue/code?
Update: Fixed title to reflect issue with a 'method' and not a 'property'. I also added that the class implements ViewModelBase.
If this is WPF, System.Windows.Threading.Dispatcher does not have a static BeginInvoke() method.
If you want to call that statically (this is, without having a reference to the Dispatcher instance itself), you may use the static Dispatcher.CurrentDispatcher property:
Dispatcher.CurrentDispatcher.BeginInvoke(...etc);
Be aware though, that doing this from a background thread will NOT return a reference to the "UI Thread"'s Dispatcher, but instead create a NEW Dispatcher instance associated with the said Background Thread.
A more secure way to access the "UI Thread"'s Dispatcher is via the use of the System.Windows.Application.Current static property:
Application.Current.Dispatcher.BeginInvoke(...etc);
Change this:
Dispatcher.BeginInvoke
to this:
Dispatcher.CurrentDispatcher.BeginInvoke
the issue is BeginInvoke is an instance method and needs an instance to access it. However, your current syntax is trying to access BeginInvoke in a static manner off the class Dispatcher and that's what's causing this error:
Cannot access non-static method BeginInvoke in static context
It's because Dispatcher is a class not a property. Shouldn't you be making your CalibrationViewModel class a subclass of some other class which has a Dispatcher property?
i've often had this issue where i do not really understand how to pass userform variables into classes. for example i have a button:
private void button1_Click(object sender, EventArgs e)
{
DoStuff();
}
and a method in the form class:
DoStuff()
{
Class123 myclass = new Class123();
}
...
...
class Class123
{
//how do i pass for example in myotherClass whether or not my checkbox on the userform is checked? i dont want to have to pass from method to method to class to class. what is the logical/smart way of handling this?
ClassData myotherClass = new ClassData();
}
how do i pass for example in myotherClass whether or not my checkbox on the userform is checked? i dont want to have to pass from method to method to class to class. what is the logical/smart way of handling this?
I think you are looking for function arguments:
// notice the declared function argument isMyCheckboxChecked
DoStuff(bool isMyCheckboxChecked)
{
Class123 myclass = new Class123(isMyCheckboxChecked);
}
private void button1_Click(object sender, EventArgs e)
{
// passing the state of the checkbox to DoStuff as an argument
DoStuff(chkMyCheckbox.Checked);
}
class Class123
{
readonly ClassData myotherClass = new ClassData();
Class123(bool isMyCheckboxChecked)
{
myOtherClass.isMyCheckboxChecked = isMyCheckboxChecked;
}
}
I can see a few things here. The code posted is rather vague, so it is hard to say what the correct answer may be.
If myOtherClass needs to know if a checkbox is checked when the checkbox changes then you should probably look into using a subscriber pattern.
However, if you mean that you just need to know if the checkbox was checked at the moment DoStuff() ran, there is nothing wrong about passing a variable. In fact, passing a variable is the preferred way - it's what variables exist for. That said, you need to pass variables intelligently; if you find that you are just slinging parameters across classes constantly, that's a sign of poorly-designed code. If you need to pass some parameters to myClass to tell it what to do, build them into a (descriptively named) class of their own, and pass that class to myClass's constructor instead of a long list of parameters.
I disagree with this approach.
Any 'smart' method, if it even exist, will break the golden rules of Object Oriented Programming.
An object is a self contained item of data that can only be accessed or changed in a controlled way. This prevents side effects, a common problem in procedural code, where data is globally accessible. In OOP, the objects can receive or send messages to other objects only by calling their methods.
EDIT: To show a way to do it
public static class MyApp
{
public static bool MyCheckBox {get; set;}
}
in your doStuff
MyApp.MyCheckBox = this.checkBox1.Checked;
inside a method of your myOtherClass
if(MyApp.MyCheckBox == true)
...
this is the same as using a global variable in the old days of procedural languages. This paves the way to difficult to track bugs and creates state mode that render an application hard to maintain
I need to attach an event handler to an object, and I placed this code on a button click event. However, I noticed that this will cause the same event to attach multiple times with each click.
Is there a way to run a piece of code on class creation? The class in question is a static class btw.
I can do something like:
if (bool == false)
{
attach event handler;
bool = true;
}
Just not sure if this is the right way to do it. Thanks.
There are static constructors, that are (in principle) only run once per class.
Something like this:
public static class MyStaticClass
{
public static int MyStaticProperty;
//no accessors required, as this is never explicitly invoked
static MyStaticClass() //no parameters either
{
MyStaticProperty = 100;
}
}
....
//writes: 100
Console.WriteLine(MyStaticClass.MyStaticProperty);
However, if a constructor won't do it, because you have some parameters that need to be set, or there are some prerequisite steps that need to be done, I would indeed recommend a private boolean check, as you have done.
You use a constructor - it will run on class creation.
Constructors are class methods that are executed when an object of a class or struct is created. They have the same name as the class or struct, and usually initialize the data members of the new object.
For static classes, use static constructors:
A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced.
try
if(Button1.Click == null)
Button1.Click += new System.EventHandler(this.myEventHandler);