I have a function named private void QuizReset() on a form called FormMain and I was wondering if there was a way to access it on a form named Form2 without getting build errors? Might seem like a really simple question or something I'm missing, but I've tried changing it from private to public and I mustn't be doing it right as I get build errors and such. I'm all up for modifying it if it can be done without errors. If anyone could help me out that'd be great.
Thank you.
The current code for the function is:
private void QuizReset()
{
//resets the difficulty selection control and shows it again upon resetting the quiz
difficultySelectionControl.Reset();
difficultySelectionControl.BringToFront();
btnNext.Enabled = false;
lblStatus.Text = "Please select a difficulty";
iCorrectACount = 0;
iCurrentQIndex = 0;
}
If you want to access the method it can't be private. static public is a simple work around. Then you can call it with MainForm.LoadQuiz(). Another option is to move the logic into a helper class.
Put them in a public common class. Then put LoadQuiz function as a private static method that belongs to that class. You can also make LoadQuiz a static public, which is quick and dirty. I don't recommend that, because exposing methods publically could cause memory and allocation problems down the road.
I think you cannot put this function in common static class, because, if I understand right, the function use a controls of the form(btnNext.Enabled = false;). This mean that function can/must be used only with instance of the FormMain class.
If you want call this function from Form2, then Form2 must to have a reference of FormMain.
My approach will be next:
Create a variable in Form2:
private FormMain frmMain;
Then create a constructor of Form2 where i assign a reference of FormMain in Form2
public Form2(FormMain inFrmMain)
{
this.frmMain = inFrmMain;
}
Code for opening of Form2 will be then:
Form2 frm2 = New Form2(this);
frm2.Show();
After this you can call your FormMain function from Form2:
this.frmMain.QuizReset()
And of course, at first change function QuizReset to public
Related
I have a windows Forms project with 8 forms. Everytime I open a new Form I do this:
new FormX().Show();
this.Hide();
Due to this, I realized I am creating Multiple objects of Same form while it's previous copies exist, i.e if once i opened FormX and then I hid it and called next Form. When my work was done with it and I had to go back to FormX, I created the object once again. I do not want to do this as this consumes memory and makes application slow.
I want to know if there is a way to store all the objects of all forms in one class/form like this:
Form1 obj1=new Form1();
Form2 obj2=new Form2();
and everytime i need to make one of them visible I simply write obj1.show() or obj2.show()
Is it possible to store these objects in Program.cs class?
The question is somewhat vague. But based on what you seem to be asking, you have a couple of options in addition to the one you propose:
Don't try to reuse the form. Instead of calling Hide() just call Close().
Implement each Form class as a singleton. Then make sure you don't close each form (i.e. continue to call Hide() instead), and access the relevant instance from the static instance property.
Example of #2:
class Form1 : Form
{
private static readonly Lazy<Form1> _instance = new Lazy<Form1>(() => new Form1());
public static Form1 Instance { get { return _instance.Value; } }
}
then elsewhere…
Form1.Instance.Show();
// ... do some stuff with Form1
Form1.Instance.Hide();
As you can see, the class names I used are default names of classes generated by Visual C#. How can I go about changing values in a TextBox named "textBox2" (this TextBox is placed in the Form1 design already) from the "Program" class? I have tried a lot of things and every thing I tried results in this error (or similar to): An object reference is required for the non-static field, method, or property 'WindowsFormsApplication1.Form1.textBox2'
Please, if you can, try to keep your answers simple, thank-you.
First, you generally shouldn't access controls such as textboxes from your Program class. Instead you should do this in the Form1.cs file. Form1 is a class, and it has a protected field for textBox2 so it is inaccessible outside the class. If you want to change the value from Program.cs, you should add a public function to Form1 that sets the value of textBos2.Text.
Secondly, you appear to be just typing class names instead of the name of the instance. The difference is Textbox is a class, textBox1 and textBox2 are instances. Textbox.Text is invalid because you need to specify WHICH textbox you are trying to get or set the text for. It's the same with Form1.textBox2. Form1 is a class and there can be many of them. You must specify the name of the instance of the form to access its public members.
UPDATE:
I'm just going to give you a brief explanation of the difference between a class and an instance of a class, static fields and non-static fields. Please forgive any wordiness.
When you create a new windows forms application Visual Studio will create a Form1 type for you. Form1 is a class. Program then uses Form1 to create a form instance and show it. The code would look something like:
Form1 form = new Form1;
In this case, form is the instance. You can create multiple instances of Form1. Each instance will have the textBox2 you created, which is an instance of the Textbox class. Just like you have to do textBox2.Text to get the text of the second Textbox you created on the form, you must specify form.textBox2 (or your public method that sets the textBox2.Text value). Form1, even though it has a number after it is a class, and form is the instance. They have the same relationship as Textbox and textBox2.
Non-static members are accessible to an instance. Static members are accessible to the class. A static member can not access a non-static member unless it is through an instance.
You'll need to have an instance of your Form1 to do this.
Form1 frm = new Form1();
Then you'll have to build a public method to access to your textbox, cause it's a private member.
Form1.cs:
public void UpdateText(string newValue)
{
this.textbox2.Text = newValue;
}
Finally:
frm.UpdateText("new text");
You have to create a new instance of the Form1 class.
You can't "reach" a non static var without new()
var form1 = new Form1();
form1.textBox2.Text= "aaa";
Make textBox2 public or internal. To do so adjust the Modifier property of it from the designer (Properties). Then do this in Main from "Program" class:
Form1 f = new Form1();
f.textBox2.Text = "sdfsdf";
Application.Run(f);
This is absolutely a bad design anyways.. Tell us why you would want this, we would be helpful in dealing with the real problem.
I'm just curious to know that there is the (Name) property, which represents the name of the Form class. This property is used within the namespace to uniquely identify the class that the Form is an instance of and, in the case of Visual Basic, is used to access the default instance of the form.
Now where this Default Instance come from, why can't C# have a equivalent method to this.
Also for example to show a form in C# we do something like this:
// Only method
Form1 frm = new Form1();
frm.Show();
But in VB.Net we have both ways to do it:
' First common method
Form1.Show()
' Second method
Dim frm As New Form1()
frm.Show()
My question comes from this first method. What is this Form1, is it an instance of Form1 or the Form1 class itself? Now as I mentioned above the Form name is the Default instance in VB.Net. But we also know that Form1 is a class defined in Designer so how can the names be same for both the Instance and class name?
If Form1 is a class then there is no (Static\Shared) method named Show().
So where does this method come from?
What difference they have in the generated IL?
And finally why can't C# have an equivalent of this?
This was added back to the language in the version of VB.NET that came with VS2005. By popular demand, VB6 programmers had a hard time with seeing the difference between a type and a reference to an object of that type. Form1 vs frm in your snippet. There's history for that, VB didn't get classes until VB4 while forms go all the way back to VB1. This is otherwise quite crippling to the programmer's mind, understanding that difference is very important to get a shot at writing effective object oriented code. A big part of the reason that C# doesn't have this.
You can get this back in C# as well, albeit that it won't be quite so clean because C# doesn't allow adding properties and methods to the global namespace like VB.NET does. You can add a bit of glue to your form code, like this:
public partial class Form2 : Form {
[ThreadStatic] private static Form2 instance;
public Form2() {
InitializeComponent();
instance = this;
}
public static Form2 Instance {
get {
if (instance == null) {
instance = new Form2();
instance.FormClosed += delegate { instance = null; };
}
return instance;
}
}
}
You can now use Form2.Instance in your code, just like you could use Form2 in VB.NET. The code in the if statement of the property getter should be moved into its own private method to make it efficient, I left it this way for clarity.
Incidentally, the [ThreadStatic] attribute in that snippet is what has made many VB.NET programmers give up threading in utter despair. A problem when the abstraction is leaky. You are really better off not doing this at all.
VB is adding a load of code into your project behind your back, basically.
The easiest way to see what's going on is to build a minimal project and look at it with Reflector. I've just created a new WinForms app with VB and added this class:
Public Class OtherClass
Public Sub Foo()
Form1.Show()
End Sub
End Class
The compiled code for Foo looks like this when decompiled as C#:
public void Foo()
{
MyProject.Forms.Form1.Show();
}
MyProject.Forms is a property in the generated MyProject class, of type MyForms. When you start diving into this you see quite large amounts of generated code in there.
C# could do all of this, of course - but it doesn't typically have a history of doing quite as much behind your back. It builds extra methods and types for things like anonymous types, iterator blocks, lambda expressions etc - but not in quite the same way that VB does here. All the code that C# builds corresponds to source code that you've written - just cleverly transformed.
There are arguments for both approaches, of course. Personally I prefer the C# approach, but that's probably no surprise. I don't see why there should be a way of accessing an instance of a form as if it was a singleton but only for forms... I like the language to work the same way whether I'm using GUI classes or anything else, basically.
I'm trying to change a listbox in my main form from another file (nodes.cs) which contains another class. I created a class in my main form that changes the textbox for me so all I need to do it pass the string to it. Unfortunately, I can't access the function from the other class unless I make the String-changing-class static. If I make it static, I can't change the listbox without getting an error:
An object reference is required for the non-static field, method, or property...
I know this means I need to create the object or make it non-static. I find the whole class thing rather confusing. I have to initiate a whole new form object to access it? Anyways.
How do I go about accessing a Listbox from another Class, contained in another file? The two classes are in the same namespace.
there's no real point in adding what I have, it's a huge amount of code, and i erased everything I've tried already...
MAIN.CS
namespace neuralnetwork
{
public partial class mainform : Form
{
yada yada
public static void changetext(string text)
{
listbox1.items.add(text);
}
}
}
Secondary.cs
namespace neuralnetwork
{
class lolercopter
{
public static void dolol()
{
//here is where I want to change the mainforms textbox.
mainform.changetext(s);
}
}
}
This is essentially what I have. I've been reading for over an hour on this...
You can pass a reference to mainform into your method:
public static void dolol(mainform frm)
{
frm.changetext(s);
}
Your question leads me to suspect that you have some serious architecture issues with this application, but hopefully this solution can work for you.
classes are like blueprints.
What you're asking is like asking how to open the door down the hall on the blueprint.
It sounds like you want action on one form to trigger action or changed state on another form. That could be achieved by storing state in a database, or in memory, but ideally by having a reference to the instantiated mainform.
How is your nodes class created? Is it created by the form? If so, you could pass in a reference to the form when you create the nodes class.
For example, say you have this code in a callback in the form.
var nodes = new Nodes();
nodes.UpdateSomething( args );
You could change the constructor for the Nodes class so that it takes a reference to form. This is called Dependency Injection, specifically constructor injection. Your class has a dependency on the form, you provide the form when you create the class.
var nodes = new Nodes( this ); // "this" is a reference to the form
nodes.UpdateSomething( args );
Your Nodes class would then use the helper as:
public class Nodes
{
private Form TheForm { get; set; }
public Nodes( Form form )
{
this.TheForm = form;
}
public void UpdateSomething( EventArgs args )
{
...
this.Form.ChangeText( newValue );
...
}
}
The basic idea is to provide the class the resources that it needs access to via the constructor so you don't have to make use of long-lived object references and static classes.
EDIT: I've updated this to reflect your code sample. Note that you're not providing a new class in the form to change the list box, but rather a method.
In the form.cs file I have two buttons,a memo and a timer.My question is: How do I access the timer or the memo from another cs file?
I've tried to make the objects public,but it didn't work,please give me a source or a project,so I can see where I'm mistaken.
Thanks!
Select your button in designer, go to it's properties and change "Modifiers" property from Private to Public.
Then you can get access to it from another class, something like this:
public static class Test
{
public static void DisalbeMyButton()
{
var form = Form.ActiveForm as Form1;
if (form != null)
{
form.MyButton.Enabled = false;
}
}
}
Note: it's just an example and definitely not a pattern for good design :-)
I worry whenever I hear someone talking about "another .cs file" or "another .vb file". It often (though not always) indicates a lack of understanding of programming, at least of OO programming. What's in the files? One class? Two?
You're not trying to access these things from another file, you're trying to access them from a method of a class, or possibly of a module in VB.
The answer to your question will depend on the nature of the class and method from which you're trying to access these things, and the reason why you want to access them.
Once you edit your question to include this information, the answers you receive will probably show you that you shouldn't be accessing these private pieces of the form in classes other than the form class itself.
There is Form object already instanced in Program.cs, except it have no reference. With simple editing you can turn
Application.Run(new Form1());
to
Application.Run(formInstance = new Form1());
declare it like
public static Form1 formInstance;
and use
Program.formInstance.MyFunction(params);
Although I agree with John Saunders, one thing you may be doing wrong, assuming that you have everything accessible through public modifiers, is that you don't have the instance of that form.
For example, this is how you would do it:
Form1 myForm = new Form1;
string theButtonTextIAmLookingFor = myForm.MyButton.Text;
I am assuming that you may be trying to access it like it's static, like this:
string theButtonTextIAmLookingFor = Form1.MyButton.Text;
Just something you might want to check.
The intuitive option is simply to make the control field public
Here is a very good solution to solve this issue..
http://searchwindevelopment.techtarget.com/answer/In-C-how-can-I-change-the-properties-of-controls-on-another-form