Static class object reference - c#

I have one main form and a static class when i access static class member it gives me nullreference error . Previously it was working fine donot know what happend . Any one can suggest what is wrong.
code snap:
namespace MyNamespace
{
public partial class myForm : Form
{
public myForm()
{
InitializeComponent();
}
private void myForm_Load(object sender, EventArgs e)
{
My_Static_Data_Class.player_name="Demo Player"
}
}
public static class My_Static_Data_Class
{
public static string player_name = "";
}
}
please help?

You're either accessing the static class member before it was set to "Demo Player". For example, you are trying accessing My_Static_Data_Class.player_name in Program.cs code before it calls the main form from the Main[] method. Alternatively you're might be setting My_Static_Data_Class.player_name to null elsewhere in code and then accessing it.
Check all the references in code editor and follow it up. To do this, right click on My_Static_Data_Class.player_name in Visual Studio editor, and choose Find All References menu item.

Related

Populate list in form from a table (Entity Framework) then use in other places in the form code

New C# and Entity Framework user. I want to put the results of a table into a C# list. I want to reference this list in multiple form events. I will cycle through the list from beginning to end throughout the life of the form.
Currently, I have this code (snippet):
public partial class FrmMain : Form
{
private readonly admEntities _admEntities = new admEntities();
public FrmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
var exhibitor = _admEntities.Exhibitors.ToList();
// Put the first value in a text box - this works
txtCurrentSaleOrder.Text = exhibitor.First().SaleOrder.ToString();
}
}
I was hoping to use the exhibitor variable elsewhere on other events. However, I am unable to reference it.
I have not been successful in my searching and coding attempts to resolve this problem so far. Any pointer in the right direction would be appreciated.
One thing I tried was to put this code in a class above FrmMain(). That also failed. Probably due to not fully understanding classes yet.
You should make exhibitor a field, which is a fancy way of saying declare it outside of a method, inside of your class. Here is an example where exhibitor can be accessed from anywhere else in the class.
public partial class FrmMain : Form
{
private readonly admEntities _admEntities = new admEntities();
//It's unclear what exhibitor is in your question, so I'm using generic code that will allow it to work regardless.
private Type exhibitorType = typeof(admEntities.Exhibitors);
private List<exhibitorType> exhibitor = new List<exhibitorType>();
public FrmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
//Can reference here
exhibitor = _admEntities.Exhibitors.ToList();
txtCurrentSaleOrder.Text = exhibitor.First().SaleOrder.ToString();
}
private void AnotherMethod()
{
//Can reference exhibitor here too.
}
}

Passing Variable from another class into a form

I am struggling with passing a Variable (a string) in C# for a special problem:
Overview:
I am writing a plugin for a purchased program at my company. The program (or better: the programs support) gives the user basic C#-Code which basically just opens a form, and connects the program with whatever I write down in the forms code.
As it is a Visual-Studio-Solution I get some files: "MyUserInterface.cs" and "MyUserInterface.Designer.cs".
"MyUserInterface.Designer.cs" defines the look of my form, i thing the most importand parts for my problem are:
partial class MyUserInterface
{
[...]
private void InitializeComponent()
{
[...]
this.f_status = new System.Windows.Forms.Label();
this.SuspendLayout();
[...]
//
// status
//
this.f_status.Name = "status";
this.f_status.Text = "WELCOME TO MYPLUGIN v2";
[...]
this.Controls.Add(this.f_status);
this.ResumeLayout(false);
this.PerformLayout();
}
[...]
private System.Windows.Forms.Label f_status;
[...]
}
The most important code from "MyUserInterface.cs" is:
partial class MyUserInterface
{
[...]
public MyUserInterface()
{
InitializeComponent();
}
[...]
private void click_compute(object sender, EventArgs e)
{
//Basically everythings runs here!
//The code is opend in other classes and other files
}
}
Now as i marked in the code section, my whole code runs in the "click-compute" Function and is "outsourced" into other classes.
One important part of my code is found in "statushandler.cs":
class statushandler
{
[...]
public static void status_msg(string c_msg)
{
[...]
f_status.Text = c_msg; // And here is my problem!!
[...]
}
}
Problem:
In my special case, i try to change the text of the "f_status"-Lable while running my code by using the "status_msg" Function!
While I pass variables between classes a few times in my code. A cannot figure out, why this explicit one cant be found inside "statushandler". (It is no problem as long as I stay inside the original "click_compute", without going into a different class).
What I already tried:
1.) I tried to change basically everything in "MyUserInterface" into "public",
2.) Also I tried to call f_status in status_msg like MyUserInterface.f_status.Text,
3.) Write a Getter/Setter-Function in "MyUserInterface.(Designer.)cs" (both), which was catastrophic because i couldn't define the Label in the InitializeComponent anymore.
4.)
a.)Read a lot of Stackoverflow-Threads about passing variables between classes, which all didn't helped, all solutions I found, are working between classes, but not in this special case.
b.)Watched a lot of youTube tutorials, same result.
c.)Read some stackoverflow-Threds about passing variables between different Forms, but they all had in common, that the "displaying-form" was opend AFTER the variable was known. In my special case the form is opened all the time, and can't be closed, nor reopened...
And now I am out of ideas!
I wouldn't be surprised, if I do not see some details, but I can't found them... I would be very happy, when somebody could help me!
My question:
How can I change the text of my lable from another class?
Your method is static while your form has instance. So your static method does not know anything about your form. You can add MyUserInterface parameter to static method
public static void status_msg(MyUserInterface form, string c_msg)
{
[...]
form.f_status.Text = c_msg; // And here is my problem!!
[...]
}
If you have single instance form (only one instance is created at a time) you can have static property with it's reference:
partial class MyUserInterface
{
public static MyUserInterface Instance { get; private set; }
[...]
public MyUserInterface()
{
InitializeComponent();
Instance = this;
}
}
With this solution you can use your old method:
class statushandler
{
[...]
public static void status_msg(string c_msg)
{
[...]
MyUserInterface.Instance.f_status.Text = c_msg; // You have instance of yout form here
[...]
}
}
Of course you should protect against null/ Disposed form etc.
Create a public property on the specific class in your 1st Form that gets the label's value like this:
public string Name {get {return Label1.Text}; set {Label1.Text = value}; }
Then in your 2nd Form:
public Form2(Form1 form)
{
string name;
name = form.Name;
}

Unable to access methods in another winform

I have two projects in my solution called ePad demo and PLHardwareHelper. I have added a reference to the PLHardwareHelper for the epad demo and I can successfully access methods in epad from hardwarehelper.
The problem is though that I cannot access anything in hardware helper from epad. I can't added a reference because it says it will result in a circular reference. I can't even add the namespace as a reference in the form.
How can access methods in hardwarehelper from within epad without adding a reference?
I have added a third reference called ApplicationJoin so I can add it's reference to both the other projects but it still complains that it can't find it. I have added an image below to demonstrate:
The code from ApplicationJoin:
namespace ApplicationJoin
{
public partial class Form1 : Form
{
public static string _imagevalues = "";
public Form1()
{
InitializeComponent();
}
public static void ImageValues(string value)
{
_imagevalues = value;
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
The issue:
The error on the blue squiggly line is:
The name 'ApplicationJoin' does not exist in the current context
I have tried rebuilding and cleaning the solution but it still doesn't work.

Access and modify form listbox from another class

I'm having some issues accessing and modifying a listbox control from another class.
Here's the MainForm, which holds the listbox:
public partial class MainForm : Form
{
private static MainForm mainForm = new MainForm();
internal static MainForm init()
{
return MainForm.mainForm;
}
public MainForm()
{
InitializeComponent();
}
}
And here's the second class that I'm using to attempt to modify the listbox (the items are added from an event):
public class Utils
{
void ItemsReceived(object sender, DataReceivedEventArgs<ListboxItems> e)
{
MainForm.init().listBox1.Items.Add("test");
}
}
Using this code setup, nothing is added to the listbox. Any ideas? Or even a better way to tackle this?
Typically visual studio generates the following code in a Program.cs file:
Application.Run(new MainForm());
If this line still exists, your static mainForm variable will hold a different instance of MainForm than the one visible when running the application. If I'm right, change the line in Program.cs to:
Application.Run(MainForm.init());
On a side note, while using the singleton (anti)pattern, consider changing the name of that method to GetInstance() because init() appears to initialize something.

How to access controls in other class

I'm learning C# and what I need is to access control on a Form from other class (the same namespace).
I know there is a lot of posts on this topic here but didn't find complete solution 'for dumbs' so I write here what I figured out and please tell me - is this the correct way ?
Background: I have some 'debugging' form in my app and I need all other forms to be able to log their activity into this form. There is some ListBox control where all the logs from other forms are written. When I (or one of my tester-friends without Visual Studio) play around with app and something bad happens, I can look on that debug-form to see all detailed logs what happened just before that 'moment of error'.
My main form of the app (frmMain):
namespace myNamespace {
public partial class frmMain : Form {
private frmDebug debug; // frmDebug is declared in other class
// we will hold reference to frmDebug form in 'debug'
public frmMain() { // constructor of the main form 'frmMain'
InitializeComponent();
debug = new frmDebug(); // we create new instance of frmDebug immediately when
} // our main form is created (app started) and whole time
// of running this app we can access frmDebug from
// within frmMain through 'debug' variable
// clicking button 'btnLoggingTest', the log is written
// in the 'frmDebug' form even if it is closed (not visible)
private void btnLoggingTest_Click(object sender, EventArgs e) {
debug.Log("log this text for me please");
}
// Click handler of the button 'btnShowDebug' :
private void btnShowDebug_Click(object sender, EventArgs e) {
debug.ShowDialog(); // here we can show frmDebug (in 'modal' style)
} // just to see what log-information is written there
} // frmMain class
} // namespace
And here is the code of class frmDebug itself :
(there is only one Listbox placed on the form)
namespace myNamespace {
public partial class frmDebug : Form {
public frmDebug() {
InitializeComponent();
}
public void Log(string txt) { // this is the actual 'Log' function (or method)
this.listBox1.Items.Add(txt);
Application.DoEvents(); // if the logging takes place in some
} // computing-intensive 'loop' or function,
// (or in my case FTP login and upload process)
// 'DoEvents' ensures every log appears immediately
// after the 'Log()' was called. Otherwise all logs
// would appear together at once, as soon as the
// computing-intensive 'loop' is finished
} // class frmDebug
} // namespace
I have a strange feeling in my stomach I'm doing it all wrong so please tell me how to do it properly :) If it's OK, hope it helps somebody like me.
Thank you !
Your application has probably a class called "Program". There you will find the code
var mainForm = new frmMain();
Application.Run(frmMain);
Create a static property for the debugging form in this class
public static frmDebug DebuggingForm { get; private set; }
Change the startup code like this
DebuggingForm = new frmDebug();
var mainForm = new frmMain();
Application.Run(frmMain);
From other classes you can access this form like this
Program.DebuggingForm.Log("log this text for me please");
Program.DebuggingForm.Show();
I think you don't have to keep debugging form in memory. You can write logs to some object. E.g. static log:
public static Log
{
private static List<string> _messages = new List<string>();
public static Write(string message)
{
_messages.Add(message);
}
public static IEnumerable<string> Messages
{
get { return _messages; }
}
}
You can add log messages from every point of your application via
Log.Write("log this text for me please");
If you need to view those messages just create and show debug form:
private void btnShowDebug_Click(object sender, EventArgs e) {
using (frmDebug debug = new frmDebug())
debug.ShowDialog();
}
In debug form on load assign Log.Messages to your listbox.
A different approach would be to have an Event Sink that would act as a publish subscribe hub for your debug information, that way you don't get a dependency on the debug form all over the place, something like:
public class EventSink
{
private static readonly IList<Action<string>> _listeners = new List<Action<string>>();
public static void RegisterListener(Action<string> listener)
{
_listeners.Add(listener);
}
public static void RaiseEvent(string message)
{
foreach (var l in _listeners)
l(message);
}
}
in the constructor for your frmDebug you would do:
EventSink.RegisterListener(msg=>listBox1.Items.Add(msg));
and every time you need to add a message to the debug console you would do:
EventSink.RaiseEvent("this is a debug message");
This way you could then register new listeners to do different things, like send you an email when some specific event happens, etc. and you are not coupled with your debug form (decoupling is good:)

Categories