I am overlooking something simple I think. I have a form with a checkbox. I need to know if the checkbox is checked in a different cs file/class to know whether to make a column header Option1 or Option2.
Form1 (Public partial class) code:
public bool Checked
{
get
{
return checkBox1.Checked;
}
}
In my Export1 class I have private void CreateCell1 that takes in the data to be exported (creating an excel file from a datatable). The section of code I can't get to work is:
if (Form1.Checked.Equals("true"))
{
newRow["Option1"] = date2;
}
else
{
newRow["Option2"] = date2;
}
I am getting -Error 1 An object reference is required for the non-static field, method, or property 'Matrix1.Form1.Checked.get'
What did I overlook?
Well, the problem here is exactly what the compiler is telling you. You need an object reference in order to access the property.
Allow me to explain.
In C#, by default, class members (fields, methods, properties, etc) are instance members. This means that they are tied to the instance of the class they are a part of. This enables behavior like the following:
public class Dog
{
public int Age { get; set; }
}
public class Program
{
public static void Main()
{
var dog1 = new Dog { Age: 3 };
var dog2 = new Dog { Age: 5 };
}
}
The two instances of Dog both have the property Age, however the value is tied to that instance of Dog, meaning that they can be different for each one.
In C#, as with a lot of other languages, there are things called static members of classes. When a class member is declared static, then that member is no longer tied to an instance of the class it is a part of. This means that I can do something like the following:
public class Foo
{
public static string bar = "bar";
}
public class Program
{
public static void Main()
{
Console.WriteLine(Foo.bar);
}
}
The bar field of the Foo class is declared static. This means that it is the same for all instances of Foo. In fact, we don't even have to initialize a new instance of Foo to access it.
The problem you are facing here is that, while Form1 is not a static class and Checked is not a static property, you are treating it as such. In order for what you are trying to do to work, you need to create an instance of Form1 and access that instance's Checked property.
Depending on how your program is structured, there are many ways of doing this. If Form1 is created in the scope where you are trying to access Checked, then this will be straightforward. If Form1 is what spawns the new scope, then common practice is to pass a reference to it in the constructor.
For example, if Form1 creates a new Form2 then we do the following:
public class Form2 : Form
{
private Form1 parent;
public Form2(Form1 parent)
{
this.parent = parent;
InitializeComponent();
}
}
And then you can access parent throughout Form2. Of course, depending on the structure of your program, the exact implementation will be different. However, the general pattern is the same. Pass the reference to Form1, from the scope it was created in, to the new class, and then access it from there.
One way or another, you need to access the specific instance of Form1 that you're trying to check.
A few ways to do this are:
Pass the instance to the class constructor
Setting a public property of the other class to the instance of the form
Pass the instance to the method directly
For example:
public class SomeOtherClass
{
// One option is to have a public property that can be set
public Form1 FormInstance { get; set; }
// Another option is to have it set in a constructor
public SomeOtherClass(Form1 form1)
{
this.FormInstance = form1;
}
// A third option would be to pass it directly to the method
public void AMethodThatChecksForm1(Form1 form1)
{
if (form1 != null && form1.Checked)
{
// Do something if the checkbox is checked
}
}
// This method uses the local instance of the Form1
// that was either set directly or from the constructor
public void AMethodThatChecksForm1()
{
AMethodThatChecksForm1(this.FormInstance);
}
}
This class would need to be instantiated by the instance form1 using one of these methods:
// Pass the instance through the constructor
var someOtherClass = new SomeOtherClass(this);
// Or set the value of a property to this instance
someOtherClass.FormInstance = this;
// Or pass this instance to a method of the class
someOtherClass.AMethodThatChecksForm1(this);
Related
When I create a new thing from the MyClass class it triggers an exception.
namespace class_test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
MyClass thing = new MyClass();
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = thing.x.ToString();
thing.x++;
}
}
code for the class:
namespace debugging_class
{
class MyClass : Form1
{
public int x = 100;
}
}
By testing I found out that the : Form1 from the class code is the issue. I am using that because I want to access Form1 objects in the class. Is there any way to do that without using : Form1?
The problem is indeed one of infinite recursion. When you create a MyClass object, it calls the constructor for that class. Because MyClass inherits from Form1 and you haven't specified a default (parameterless) constructor for MyClass, it will implicitly call the constructor for Form1.
The problem is that you have in your code for Form1 a class-level variable with a default value. When a class has a field with a default value, those variables will be implicitly set with the given value at the beginning of that object's constructor. So, for example, the code:
public class SomeClass
{
public int i = 5;
public SomeClass()
{
// Just a simple call and that's it
Console.WriteLine(i);
}
}
Will actually compile to something resembling the following:
public class SomeClass
{
public int i;
public SomeClass()
{
// Assign default values to class instance fields
i = 5;
// Execute the rest of the constructor code
Console.WriteLine(i);
}
}
So here is the problem - your Form1 class has a MyClass field with a default value of new MyClass(). That field will be assigned in Form1's constructor. Because MyClass inherits from Form1, then Form1's constructor will also get called, which will then create a new instance of MyClass, which will call the constructor for Form1 again... You see how this turns into infinite recursion? The constructors of Form1 and MyClass are calling each other back and forth forever and ever (or at least until the program reaches the limit of recursion and throws a StackOverflowException).
The reason that your code runs fine if you remove the default value and instead put the instantiation of the field inside a separate method is because that method won't get called until later in your program. MyClass's constructor will call Form1's constructor and then return, allowing your program to continue on its merry way.
A little background on my project:
I'm making a multi-form application, which consists of 1 mainform, and 6 childforms that can be called from the mainform, but only 1 childform can be active at a time. These childforms share certain parts of code, which I do not want to copy. To solve this, I have a codefile within the same namespace which holds the nessaccary code.
This codefile however, needs access to certain properties of the currently active childform.
My search has come down to using an interface to extract the needed information from the active childform.
My code is currently looking like this:
Interface:
public interface Interface1
{
TabControl tabControl_Buizen_
{
get;
}
TabPage tabPage_plus_
{
get;
}
}
Childform:
public partial class Childform : Form, Interface1
{
Interface1 dummy;
public TabControl tabControl_Buizen_
{
get { return this.tabControl_Buizen; }
}
public TabPage tabPage_plus_
{
get { return this.tabPage_plus; }
}
Methods_newTabPage methods = new Methods_newTabPage(dummy);
}
Codefile:
public class Methods_newTabPage
{
private readonly Interface1 form;
public Methods_newTabPage(Interface1 formInterface)
{
this.form = formInterface;
}
}
As you can see I'm using Methods_newTabPage methods = new Methods_newTabPage(dummy); to be able to call methods in my codefile, but the codefile requires the interface to be passed (which I filled as "dummy"). This however pops the error "A field initializer cannot reference the non-static field, method, or property Childform.dummy".
How can I let the childforms access the methods in the codefile, while also giving the codefile access to certain controls in differing childforms?
The error is easy to fix: just make dummy static.
static Interface1 dummy;
However, I don't think that will help you much. Why are you passing this dummy to Methods_newTabPage anyway? This will lead to NullReferenceExceptions inside the code file because dummy was never initialized with anything.
Don't you rather want to pass this, i.e. the current instance of Childform?
But you cannot just exchange dummy with this like so:
// Compiler error "Keyword 'this' is not available in the current context".
Methods_newTabPage methods = new Methods_newTabPage(this);
Instead you have to add a constructor that creates Methods_newTabPage:
public partial class Childform : Form, Interface1
{
private Methods_newTabPage methods;
public Childform()
{
methods = new Methods_newTabPage(this);
}
public TabControl tabControl_Buizen_ { get { return this.tabControl_Buizen; } }
public TabPage tabPage_plus_ { get { return this.tabPage_plus; } }
}
Try adding a constructor that initializes the field methods.
Also I don't see how that dummy makes sense. Instead initialize methods via methods = new Methods_newTabPage(this); in the constructor.
i have in the main window variable
example:
public partial class MainWindow : Window
{
internal int i;
public MainWindow()
{
InitializeComponent();
}
}
and i want to use him in child window and for that i do him internal (the two window in the same namespace) and the child window still doesn't recognize the variable
what i'm suppose to do?
You should create a public property on the child window of type int. When you create the child window then set that property based on the value of the field in the parent window.
It appears that you want to be able to not just read the variable in the child class, but also modify it and have that change reflected in the parent form, so that will complicate the answer.
We'll need to start off with a helper class. Because the data we're interested in is an int (which is a value type) we'll need something that is a reference type (i.e. a class).
public class Wrapper<T>
{
public T Value { get; set; }
}
So we'll start by not having an integer in the parent form, but instead an instance of this class:
public class Form1
{
private Wrapper<int> data = new Wrapper<int>(); //TODO give better name
//...
}
Next we'll need a public property on the child form; rather than an int we'll use this new class:
public class Form2
{
public Wrapper<int> Data { get; set; }
//...
}
Now when we create the child class we'll set the property based on the value in the parent class:
public void someMethod()
{
Form2 childForm = new Form2();
childForm.Data = data;
childForm.Show();
}
Now that we've done all this we've ensure that both the parent and child class have a reference to the same instance of Wrapper, so any changes to the Value property of the Wrapper instance (from either class) will be "seen" by either reference.
I am trying to set/read a variable in class bluRemote from another namespace/class like so:
namespace BluMote
{
class bluRemote
{
public string cableOrSat = "CABLE";
........
}
}
and the other cs file (which is the form):
namespace BluMote
{
public partial class SettingsForm : Form
{
if (BluMote.bluRemote.cableOrSat == "CABLE")
{
BluMote.bluRemote.cableOrSat = "SAT";
}
.......
}
}
I know i am doing it wrong but I'm more used to doing stuff like this in VB so its like night and day ha :o)
What you are trying to do is work with static variables so you would need to change your class to this:
namespace BluMote
{
public static class bluRemote
{
public static string cableOrSat = "CABLE";
........
}
}
It is better if you stay away from static classes (for the most part) and instead focus on an object oriented approach where you have an instance (object) of bluRemote.
So instead of making the bluRemote class static you keep it the same and do:
public partial class SettingsForm : Form
{
private bluRemote _remote = new bluRemote(); // possibly created somewhere else
public void SomeFunction()
{
if (_remote.cableOrSat == "CABLE")
{
_remote.cableOrSat = "SAT";
}
}
.......
}
You're trying to access an instance variable - i.e. one which has a potentially different value for each object - just by class name. That only works for static variables.
You need to have an instance of bluRemote, and ask that for its value. However, I would strongly suggest that:
You rename your class to follow .NET naming conventions
You don't make variables public; use properties
Also note that there's only one namespace here - BluMote. Both of your classes are declared in that namespace.
As you've declared the cableOrSat field, you'll need to set it on an instance of the bluRemote class, but you are trying to set it using the name of the class itself.
If you declare the cableOrSat field as:
public static string cableOrSat = "CABLE";
You will be able to access it through the class name itself.
I have a windows form and my own class in my project
I have a method in my own class
public object Sample(Form MyForm,string ComponentName)
{
}
I want to get components of the "MyForm" from another class How Can I Make THIs?
form class
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
MyOwnClass
public class Sample
{
public object GetComponentMethod(Form form,string ComponentName)
{
////
}
}
Have you tried with:
Control myControl= form.controls.Find(...)?
updated
Sorry but in this case I cannot understand what are you looking for!
updated
you have to create a public property Components! So you can retrieve data you need!
It looks like you are just trying to access members of one object from another object.
If so you need to expose some way of accessing a specific instance of a class.
If you will only ever have one instance (of say your Form1) the simplest way is to expose that single instance via a public static property. This is called a singleton pattern:
public partial class Form1 : Form
{
public static Form1 Singleton { get; private set; }
public Form1()
{
Form1.Singleton = this;
InitializeComponent();
}
}
You can the access your Form1 instance using Form1.Singleton.SomeProperty from anywhere.
I am not promoting any specific Singleton pattern here, as there are too many issues over thread safety, but for your simple example this will do the job. Call the static property "Singleton" or "This" or "SolutionToMyWoes" or whatever you like!