How to reference from an existing referenced object from different form? - c#

I have in my opinion thoroughly looked for the answers in this website, but unfortunately I haven't found any or I just suck at looking at it.
I have 2 forms and 1 controller class and 1 model class or data class. In addition, ControllerClass has an array of the model class.
In Form1 I did a reference to the controller like this:
ControllerClass control = new ControllerClass();
In Form2 I want to reference from the ControllerClass I referred to in Form1.
Until now I have been doing something like:
ControllerClass control = new ControllerClass();
in Form2 but this just makes a new copy of the ControllerClass which is not very helpful to me.
So how can I use the ControllerClass that I instantiated in Form1 in Form2?

If you only need a single object from a class, you could use a singleton.
Then ofc, you will always have the same object.
There are several ways how you can implement your control as a singleton
here some examples:
http://csharpindepth.com/articles/general/singleton.aspx
For C# i prefer the nested version.

If you don't want to pass the object to other forms through the constructor (Communicate between two windows forms in C#), as others have suggested here, you can use a static object within the Form1.
For example, you could declare
public static ControllerClass control = new ControllerClass();
and then access the object like:
ControllerClass temp = Form1.control;
You can also make a second, static, class which will have the ControllerClass object (the class should be in the same namespace and not in the Form1 class), like so:
public static class ControllerStaticClass
{
public static ControllerClass control = new ControllerClass();
}
Then you can access the ControllerClass object like:
ControllerClass temp = ControllerStaticClass.control;

Related

Use a method from another class ? without opening new form?

Hey guys my issue is that i can't use the common class class1 = new class(); and just do class1.method1(); because if I make a new instance of the class it would open a new form and the class also has a constructor. I just need that one method from the class nothing more.
To use a class' instance method, you need an instance of that class; no exceptions*. If its constructor opens a form, make it so that it doesn't.
You may need to re-consider your design pattern as if this class1 you speak of is a Form then stopping the UI from showing in such a manner is not a particularly proper design pattern. Update your question with your current implementation so people can better advise you!
If you are manually instaniating and displaying a Form from within the class1 constructor you could consider an implementation like this:
public Class1(bool showForm)
{
if (showForm)
{
//Show UI
}
}
If you must you could hide the UI like so:
protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(false);
}

How can I access TextBox "textBox2" from the "Program" class?

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.

Why is there a default instance of every form in VB.Net but not in C#?

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.

referencing other class methods without creating a new instance

I have a class by itself called clientChat that does basic network stuff. I have several other classes linked to different window forms. In my first form I have a variable referenced to the chat class like so:
clientChat cc = new clientChat();
Everything works okay their, the class has been initialized and everything is in motion. After the first forms is done performing it's duty I bring up my second form that's obviously linked to a new class file.
Now my question is, how can I reference what's going on in the clientChat class without setting a new instance of the class? I need to pass data from the form to the networkstream and if I create a new instance of the class wouldn't that require a new connection to the server and basically require everything to start over since it's "new"? I'm a bit confused and any help would be great, thanks. C# on .NET4.0
You could create an instance of clientChat in the beginning of your program and then, simply pass its reference to the classes that need it.
You may want to look into the Singleton design pattern. Mr Skeet has written a good article on how to implement it in C# here. (Just use version 4. its the easiest and works fine =) )
Presumably you would either:
Create the object from the code that creates and shows both forms, and pass a reference to that same instance to both forms, or:
If you create the second form from inside the first form, pass a reference to the instance referenced by the first form to the second somehow (via a property or a constructor, for example).
In additional to #Jens's answer, there are 5 approaches on the linked page, while I think we have the 6th using Lazy<T> in C# 4.0
public sealed class Singleton
{
private Singleton() { }
private static readonly Lazy<Singleton> m_instance = new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance
{
get
{
return m_instance.Value;
}
}
}

Trying to figure how to call function from other class without making it static

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.

Categories