C#, Object reference for nonstatic field [duplicate] - c#

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

Related

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

C# Multi Windows Form Selection [duplicate]

This question already has answers here:
passing variables into another form
(5 answers)
Closed 8 years ago.
I'm working on a multi Windows Form project, where the value selected from the Combobox on one form should enable a ComboBox on another form. Could anyone tell me how to do that?
On the Combobox on Form1, some of the items on the list are "Mango", "Banana", "Papaya", "Orange".
On the Combobox on Form2, the values are 1, 2, 3, 4. So if a user select Mango or Papaya on Form 1, the combobox on form2 will be enabled for the user to select a number. Otherwise, the combobox will remain disabled.
Here's what I do.
I created a public class with 2 properties for both forms.
public class FormValues
{
private bool _secondcbb = false;
private string _firstcbb = "";
public bool SecondCbb
{
get
{
return _secondcbb;
}
set
{
_secondcbb = value;
}
}
public string FirstCbb {get; set;}
}
// ..... On Form1:
Form2 frm2 = new Form2();
FormValue val = new FormValue();
private void ComboBox1_SelectedIndexChanged(whatever inside)
{
if(ComboBox1.SelectedText == "Mango")
{
val = true;
frm2.ComboBox2 = val;
}
}
I don't do anything on Form2. Except adding the control and set the Combobox to be disabled.
Make public static method on Form 2 that will change comboBox state if comboBox item on Form 1 is selected like this:
public static void ChangeState(bool state) // Method on Form 2
{
comboBox2.Enabled = state;
}
Enable comboBox2 when item is selected:
private void comboBox1_SelectedIndexChanged(whatever inside)
{
if(comboBox1.SelectedText == "Mango" || comboBox1.SelectedText == "Papaya")
frm2.ChangeState(true);
else
frm2.ChangeState(false);
}
Why are you not setting the enabled property of the ComboBox2?
Like this:
frm2.ComboBox2.Enabled = true;
This way you also don't need the FormValue, or am I wrong?
It's not really clear what your FormValues class is doing, but I don't think it's necessary in the first place. In your Form2 create a method which does what you need that form to do:
public void SomeMethod()
{
// enable the control?
// edit the control?
}
This would allow anything which holds a reference to an instance of Form2 to manipulate it using the exposed functionality. Provide such a reference to Form1. Either it internally instantiates the instance of Form2 or it requires one as a constructor argument. Either way, Form1 should have a reference to an instance of Form2:
private Form2 Form2Instance { get; set; }
Then in your control's handler in Form1 you simply invoke the functionality on that instance:
this.Form2Instance.SomeMethod();

Passing value from dialog form to main form [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do you pass an object from form1 to form2 and back to form1?
I'm used to passing variables between windows forms by simply passing them as a parameter.
Now I have a form that is already open (let's call it FormMain), and another form that should act like a dialog (FormTask). The user cannot interact with the main form until he has filled in the information on FormTask. FormTask simply contains a single textbox, and the value of this textbox should be returned to FormMain, and kept track of as a variable. FormTask requires a parameter exerciseType. When FormTask opens it checks the value of this parameter and sets the default value of the textbox accordingly. This already works, I'm just kind of clueless on how to return my string value to the already open MainForm.
These dialogs only seem to be able to return DialogResults, which isn't what I'm after. I'm not too experienced either, and I'd rather avoid fumbling around to make my own custom dialog.
FormMain:
FormTask formTask = new FormTask(exerciseType);
formOpgaveInvoker.ShowDialog();
FormTask:
private void button1_Click(object sender, EventArgs e)
{
string opgave = textBoxOpgave.Text;
// return string value to MainForm here
}
Create public property in FormTask
public string Opgave { get {return textBoxOpgave.Text;}}
And check it after ShowDialog();
FormTask formTask = new FormTask(exerciseType);
formOpgaveInvoer.ShowDialog();
formOpgaveInvoer.Opgave; // here it is
The simplest way to do this is to add a public property to your form class to return the string.
public string opgave
{
get;
private set;
}
Assign to this property as your dialog closes and then read the property from the code that called ShowDialog():
private void button1_Click(object sender, EventArgs e)
{
opgave = textBoxOpgave.Text;
}
...
FormTask formTask = new FormTask(exerciseType);
formOpgaveInvoker.ShowDialog();
DoSomething(formTask.opgave);
Forms are just normal classes. This means, you can create properties in them.
So: Create a property and assign the value to it.
Add a property to the FormTask for example String1 like
public string String1 {get; set;}
Set String1 value in button1_Click for example,
You can access that property in MainForm like
FormTask formTask = new FormTask(exerciseType);
formOpgaveInvoer.ShowDialog();
string str = formTask.String1;

Passing object to different windows forms

I want to pass a C# object between win forms. At the moment, I have setup a basic project to learn how to do this which consists of two forms - form1 and form2 and a class called class1.cs which contains get and set methods to set a string variable with a value entered in form1. (Form 2 is supposed to get the value stored in the class1 object)
How can I get the string value from the object that was set in form1? Do I need to pass it as a parameter to form2?
Any comments/help will be appeciated!
Thanks,
EDIT: Here's the code I have at the moment: (form1.cs)
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
Form2 form2 = new Form2();
form2.Show();
}
private void button2_Click(object sender, EventArgs e)
{
if (textBox1.Text != "")
{
Class1 class1 = new Class1();
class1.setStringValue(textBox1.Text);
}
}
}
}
There are a few different ways to do this, you could use a static class object, the above example would be ideal for this activity.
public static class MyStaticClass
{
public static string MyStringMessage {get;set;}
}
You don't need to instance the class, just call it
MyStaticClass.MyStringMessage = "Hello World";
Console.WriteLine (MyStaticClass.MyStringMessage);
If you want an instance of the object you can pass the class object that you create on Form1 into Form2 with the following.
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
Form2 form2 = new Form2();
form2.MyClass = class1;
form2.Show();
}
Then create a property on Form2 to accept the class object.
public Class1 MyClass {get;set;}
remember to make the Class1 object a global variable rather than create it within button 2 itself.
Yes, in Form1 you declare an instance of Class1 and then set the parameters as needed, then you pass it to Form2. You could for example have a constructor in Form2 and have a Class1 parameter in it. Assuming that Form1 creates Form2, otherwise you have to have some way for Form1 to find Form2 to pass the instance across.
Since I have been working in ASP.Net the last couple years I have found myself working with Newtonsoft.Json a lot. Turns out to be great within WinForms too, and in this case seemed to simplify passing objects between forms... even complex ones are a breeze!
The implementation is like this:
// Set Object Property within Form
public partial class FlashNotify : Form
{
public string Json { get; set; }
}
On the form load event you can then grab your object:
private void FlashNotify_Load(object sender, EventArgs e)
{
// Deserialize from string back to object
CommUserGroupMessage msg = new CommUserGroupMessage();
msg = Newtonsoft.Json.JsonConvert.DeserializeObject<CommUserGroupMessage>(Json);
}
Lastly is passing the object to the form:
// Serialize the Object into a string to pass
string json = Newtonsoft.Json.JsonConvert.SerializeObject(msg);
FlashNotify fn = new FlashNotify();
fn.Json = json;
fn.Show();
Granted the original selected answer is probably easier, however I like this approach as it avoids the need to replicate the class within your form, which I think makes it easier to maintain (Correction: Miss correctly read the static class in the example, I at first thought it was replicated within the form).
Using Delegate you can easily pass data to a form.
Technically, a delegate is a reference type used to encapsulate a method with a specific signature and return type
Step 1
Add a delegate signature to form1 as below:
public delegate void delPassDataToFrom(Object obj);
Step 2
In form1’s any button click event handler, instantiate form2 class and delegate. Assign a function in form2 to the delegate and call the delegate as below:
private void btnSend_Click(object sender, System.EventArgs e)
{
Form2 frm = new Form2();
delPassDataToFrom del = new delPassDataToFrom(frm.retrieveData);
del(objectToPass);
frm.Show();
}
Step 3
In form2, add a function to which the delegate should point to. This function will use the object passed:
public void retrieveData(Object objPassedFromParent)
{
//use the objPassedFromParent object as needed
}

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