I have following problem i have 2 windows forms and to send data between them i figured out that in Form2(which is called by Form1) constructor i will be passing reference to Form1 .
Like this public Form2(Form callingForm)
{
mainForm = callingForm as Form1;
InitializeComponent();
}
But I would like Form2 to be singleton and somehow I don't know how to achieve that along with passing form1's reference to form2. I reviewed documentation https://msdn.microsoft.com/en-us/library/ff650316.aspx and I have no clue how to edit this example to fit my needs. So I am able to make singleton constructor or make constructor that takes reference to form1, but not both.
If Form1 is your application's Main Form then you should use --> Appliction.MainForm. That way you don't need the parameter.
Edit: I was not trying to be obtuse and not answer your question. You can create a singleton with parameters using multiple constructors, however, I would try to avoid it.
private Singleton(param1,param2)
public static Singleton MyInstance(param1,param2)
I am not sure I am understand your question very well, but I think, you can implement Lazy.. (Lazy itself implements Singleton pattern). Maybe something like this:
class Form1
{
public Form2 Callee
{
get;
set;
}
public Form1()
{
Callee = Form2.Instance(this).Value;
}
}
class Form2
{
public static Lazy<Form2> Instance(Form1 caller)
{
return new Lazy<Form2>(() =>
{
return new Form2(caller);
});
}
public Form1 Caller
{
get;
private set;
}
Form2(Form1 caller)
{
Caller = caller;
}
}
Ok i seem to have solved this problem, here is the code:
private Form1 mainForm = null;
public Form2(Form callingForm)
{
mainForm = callingForm as Form1;
InitializeComponent();
}
public static Form2 Instance
{
get
{
if (instance == null)
{
instance = new Form2(Application.OpenForms[0] as Form1);
}
return instance;
}
}
#lrb thank you, basically i had problem in this line, cuz couldn't pass anything as parameter
instance = new Form2(Application.OpenForms[0] as Form1);
and Application.OpenForms[0] helped.
Related
My problem is, I can't invoke a message into the TextBox and I can't understand why.
There is a main class and a second class, both with call to the other one.
Where is my error?
using System;
using System.Windows.Forms;
namespace Class_Test___Invoke
{
public partial class MAINFORM : Form
{
public MAINFORM()
{
InitializeComponent();
_INVOKER = this;
}
private MAINFORM _INVOKER;
private static CLASS _CLASS = new CLASS();
private void button1_Click(object sender, EventArgs e)
{
_CLASS._MESSENGER();
}
public void _LOGGING(string _MESSAGE)
{
if (InvokeRequired)
{
_INVOKER.Invoke(new Action<string>(_LOGGING), new object[] { _MESSAGE });
textBox_ausgabe.AppendText(_MESSAGE);
return;
}
else textBox_ausgabe.AppendText(_MESSAGE);
}
}
}
namespace Class_Test___Invoke
{
class CLASS
{
private MAINFORM _MAINFORM = new MAINFORM();
public void _MESSENGER()
{
_MAINFORM._LOGGING("Test");
}
}
}
You are assuming that the _MAINFORM you create in the CLASS constructor is the same instance as the form where the button was clicked, which is not the case. You have a chicken-and-egg problem. Your form creates a CLASS, and the CLASS creates a form. So now you have two different forms. (or two different CLASS instances since you don't show how the first form or CLASS is created)
You need to "connect" the form and the class, either by passing the form to the constructor as a parameter or by some other means.
Finally, I would encourage you to do some research on best practices for class and member names. It's a bit disconcerting for a seasoned C# developer to see names in all caps and prefaced by underscores.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
Newbie coder here. Working on a game of Yahtzee but can't figure out why I'm getting this error (object reference not set to instance of object) when I have corrected it already. My 'form' object is null even though I've declared an instance of it in the class constructor and a green line saying it is not being used appears.
public partial class Form1: Form {
public Form1() {
InitializeComponent();
}
private Game game;
public void ShowMessage(string message) {
lblMessage.Text = message;
}
public void StartNewGame() {
game = new Game(this);
}
private void btnRoll_Click(object sender, EventArgs e) {
game.RollDice();
}
class Game {
private Form1 form;
public Game(Form1 form) {
form = new Form1();
}
public void RollDice() {
form.ShowMessage("blahblah");
}
The "NullReferenceException" error appears over form.ShowMessage and I don't know why. I have declared a new instance of the form class in the game constructor which is run when the player selects StartNewGame which runs the StartNewGame method. The easiest way to get it working is to simply add "Form1 form" to the parameter of the RollDice() method in the Game class, and then game.RollDice(this) in the Form1 event handler. But the instruction guide for the assignment states that we shouldn't do that and we are to initialize the Form1 object in the constructor of Game. Please help I'm new and cant understand why this is happening.
Your problem is a naming conflict in your constructor:
public Game(Form1 form)
{
form = new Form1();
}
The parameter has the same name as the form level variable. This means the constructor code is newing up the variable you pass in and not the one at class level. You should either refer to the form variable with this qualifier, or preferably rename it.
A common practice is to use underscore prefix for class level variables:
class Game
{
private Form1 _form;
public Game(Form1 form) {
_form = new Form1();
}
}
Use this in constructor Game Class :
public Game(Form1 form)
{
this.form = form;
}
You are creating a new form instead of assigning the passed in form to its local variable.
class Game {
private Form1 form;
public Game(Form1 form) {
*form = new Form1();*
}
public void RollDice() {
form.ShowMessage("blahblah");
}
You should change the code so the passed in form will be assigned to its local variable like this:
public Game(Form1 form) {
this.form = form;
}
Then it should work.
Don't let your Game class know about the Form that's calling it. That really limits the reusability of your code in the future, since now any Form that tries to use the Game class has to have a ShowMessage method to call.
Instead, just have your RollDice method return a string...
class Game
{
public void RollDice()
{
// do important 'roll dice' stuff...
return "blahblah";
}
}
And then have your Form handle the return value appropriately.
private void btnRoll_Click(object sender, EventArgs e)
{
string message = game.RollDice();
lblMessage.Text = message;
}
That completely gets around the need to pass the Form into your Game class, and avoids a lot of opportunities for getting a NullReferenceException.
I am making an app for a friend, and need the user to "input" a value, and return it to the MySQL code I have. this way, what displays will change.
My problem is this: When I do "Form1 newForm = new Form1();" (this is called in DB_Application)
I get a stackoverflow error.
public partial class Form1
{
private DBApplication DB_App = new DBApplication();
private void InitializeComponent()
{
this.orderID.Text = "";
this.orderID.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.EnterKey);
.....
this.phoneNumber.Text = DB_App.phone_number;
.....
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void EnterKey(object o, KeyPressEventArgs e)
{
if(e.KeyChar == (char)Keys.Enter)
{
//converts the "orderID.Text" to an integer value.
if (!int.TryParse(orderID.Text, out newCurrentID))
MessageBox.Show("not a number");
e.Handled = true;
}
}
}
public class DBApplication : DBInfo
{
Form1 newForm = new Form1(); // infinite loop
public DBApplication()
{
OrderID();
}
private string OrderID ()
{
.... //reads the MySQL info, and outputs the value from the database.
}
}
After the User presses "enter" I need the value to go back into "DB_Application" so the MySQL command may receive it, and output a new value.
As mentioned in your comments and by others, the stack overflow is coming from your DBApplication instantiating a Form1, which in turn instantiates a DBApplication, which in turn instantiates a Form1 and so on.
Rewrite your DBApplication to take a Form1 as part of its constructor rather than instantiating its own, this will avoid the infinite recursion and likely this is want you want since the DBApplication will properly reference the open form:
public class DBApplication
{
private Form1 Form;
public DBApplication(Form1 form)
{
this.Form = form;
}
...
}
public partial class Form1 : Form
{
private DBApplication DB_App;
public Form1()
{
DB_App = new DBApplication(this);
InitializeComponent();
}
...
}
Depending on the rest of your application, you may want to instantiate DB_App after the call to InitializeComponent(). (On second look at your code, it's pretty obvious that the DB_App needs to be assigned before calling InitializeComponent().)
Also, since we don't know the full design/usage of DBApplication, perhaps you need to flip it around where the DBApplication instantiates a Form1, and the Form1 has the existing DBApplication passed in instead.
There are generally better ways of doing this (say via dependency injection), but this should be a simple way without completely breaking the architecture you have now.
If you indeed call new Form1() from DBApplication the StackOverflow comes from new DBApplication() in Form1 (it's an instance variable). How to solve the problem depends on your application logic.
I'm trying to append text in my richtextbox which is called ConsoleText. It's not working very well. I'm using a property in my form to access the richtextbox in the Class.
It looks like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Skipped the rest
public string ACText
{
set
{
ConsoleText.AppendText(value);
}
}
Now from my class's constructor.
public McDonalds(string email, string pass)
{
Form1 f = new Form1();
f.ACText = "test";
}
It's not showing any text in my richtextbox sadly. I know it works, because i can in the property use a messageBox and see that the value is passed into it.
Thanks in advance i really need help with this.
Calling Form1 f = new Form1(); does not give you a reference to an existing form, it creates a new one with blank/default values in the form's controls.
HOW to solve this greatly depends on your design. If you want to tie your class to that form implementation, our class needs either a reference to the form, a reference to the control, or the value of the control that you're interested in passed to it.
For example:
public McDonalds(string email, string pass, Form1 form)
{
form.ACText = "test";
}
A cleaner solution would be to RETURN a value from your McDonalds class and let the FORM set the control value appropriately rather than tying your class to that form class.
you can use Singleton:
Singletons make having single instances easy. They allow for single allocations and instances of data. We review the singleton types. We see one of the fastest implementations. And we review other possibilities.
public partial class Form1 : Form
{
public static Form1 instance = null;
public Form1()
{
instance = this; //add this class to singleton
InitializeComponent();
}
public void Show(string Message)
{
MyConsole.Text = Message;
}
another class:
Form1.instance.Show("blah blah");
Create Delegate in Form1 Class binded method ACText (string val), and Pass the Delegate to McDonalds Class. Fire the Delegate
namespace YourNameSpace
{
public delegate void RichTextBoxDelegate(string text);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void ACText(string s)
{
ConsoleText.AppendText(s);
}
// In Some Method Call MCDonald's form
public void ShowMcDonalds()
{
RichTextBoxDelegate deleg = new RichTextBoxDelegate(ACText);
MCdonalds ob = new McDonalds(deleg);
ob.show();
}
}
}
Pass the deleg to McDonalds form
Just fire the Delagate
public McDonalds(RichTextBoxDelegate sp)
{
Form1 f = new Form1();
sp("This is Test");
}
deleg("Test value"); // form McDonald's Form
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!