I'm pretty new to C# and I was trying out a few things. I have a label (named 'newLabel') in the form1.cs. I have a class named 'methods.cs'. In this class I have the method
public static void updateLabel()
what I want to do is:
public static void updateLabel()
{
newLabel.Text = "New Value";
}
but this doesn't work, probably because the method is in methods.cs and the newLabel is in form1.cs.
I had the same problem with declared variables. In the methods.cs I had the variable
int value;
but I couldn't use this variable in form1.cs. I fixed this by doing
public static int value { get; set; }
I have no idea what that did but it works, but I don't know how I can apply this trick with the label.
Could someone help me with this?
Thanks!
You should read up about OOP and encapsulation. Basically you want the form
to access private fields in another object (your class) - this is restricted by encapsulation, that's why you are running into problem - you can get around them by adding those fields and methods to the "public" interface that your class is declaring by making them public properties and methods, i.e in your example:
public int Value {get;set;}
Sometimes composition is used, i.e. in your example since your class is directly accessing the form you could have a form property on your class:
public Form ViewForm {get;set;}
It would be best if you learnt C# from tutorials, but the answer to this particular question lies with something called "scope"
Essentially, scope is the visibility of variables, classes, functions and objects. A variable marked "private" can only be seen within the thing that created it (if it's created inside a function it will always be private and any variables defined inside a function can only be used inside that function). If it's created inside a class only that class can use it.
Variables or functions denoted as public (this can only be done inside a class) can be seen from outside that class. To do that you would invoke myClass.myVariable to access the variable or myClass.myFunction() to access the function.
To denote the visibility of an object you use the keywords "public" or "private". Note: This only applies to variables and functions inside classes (it also applies to other things within classes, such as nested classes and structs, but that's outside the scope of this basic intro).
for example:
class myClass
{
private int myInt;
public void myfunction()
{
myInt = 1;
}
}
This will work, as myInt can be seen by anything inside myClass
class myOtherClass
{
private void myfunction()
{
myClass myObject = new myClass();
myObject.myInt = 2;
}
}
This will not, as myInt is private to myObject and only myObject can change it. myOtherClass does not have permission and it cannot see it.
class myOtherClassTwo
{
private void myfunction()
{
myClass myObject = new myClass();
myObject.myFunction();
}
}
This, thankfully, will work. myFunction was set as public in the myClass class, so it can be seen by anybody outside of the class.
Now the keyword static which you use has a whole different meaning. I advise you not to use it until you've learned about it as you're only adding additional complexity to your problems.
I hope this has cleared things up, though I must urge you to follow some real tutorials as these basics must be thoroughly detailed or you'll be caught out later on.
Since your updateLabel method accesses the label inside the form, correct object-oriented design would dictate that this method should be in the form, too. Then you have no problem accessing newLabel.
Technically speaking: newLabel doesn’t mean anything outside a form object. You could have several copies of your form, which would mean several copies of your newLabel; which of them should it refer to? Of course the computer won’t take a guess there; it’ll expect that you tell it which form you want to use.
The reason you couldn’t access the value variable is because it was private. If you had changed it simply to:
public static int value;
then it would have worked.
From the Form1, call the updateLabel method in the mothods class:
methods updateMethod = new methods();
newLabel.Text = updateMethod.updateLabel();
With this method in the methods class:
public static string updateLabel(){
return "New Value";
}
Related
I'm working on a windows forms application in c# and I can't figure out why I can't instantiate a class object from my form code. I have several classes, and from within all of those I can instantiate instances of the other classes publicly or just within methods with no problem.
However, when I try to instantiate one of those classes from my main form, it doesn't work.
It doesn't even recognize that I've just created an instance of the class.
The real kicker is that I can successfully instantiate a class from inside a method in my frmMain class:
private void Form_Load()
{
long deltaTime; int i; int page;
if (releaseMode)
{
modCanCable can = new modCanCable();
can.WaitWhileBusy();
}
All of the classes and form classes are under the same namespace too. Please let me know if you need to me to include any more information to help me find an answer!
You can only declare the global variable at the class level. Making use of that global variable must be done inside a property, method, or function.
For a global enumerator, declare it like you would any other variable
private EnumeratorClass VariableName;
Example (following naming conventions)
private MyEnum _myVariableName;
In C# all code has to be inside of a method. The line modCanCable can = new modCanCable(); declares a private field and uses a field initializer to initialize it to a new modCanCable instance. Any other refrence to the can field must be inside of a method body.
It must be done within a method or constructor. You cannot put it just in the class.
public partial class frmMain : Form
{
modCanCable cab = new modCanCable();
public frmMain()
{
cab.property = "asd";
}
}
I am a little confused about the Simplient thing variables. I have an ASP.NET Page (not MVC).
I want to create a variable at the class level which by definition is field variable because it is within a class. Example: I have a page called example.aspx and in the code behind I have about 10 different methods. I need each method to access the variable.
The key here is, I will not be accessing this variable from any other file or page:
Which is the right way?
public partial class example : System.Web.UI.Page
{
private bool firstField;
public bool FirstField
{
get { return firstField; }
set { firstField = value; }
}
OR; because this variable will not be access outside of the page or class do I simply do this:
public partial class example : System.Web.UI.Page
{
bool firstField;
I understand the use of the property for global variables but do I need to use it if the variable will not be accessed outside of a class? (My books says nothing about this part).
If you have a data member that you don't want to be accessible to other classes, then you can explicitly make it a simple private field. If you want to add logic to its read and write operations, make a private field but access it through a private property.
In any case, if you want to encapsulate the member to make it accessible only to the class, you'll have to make it private and not expose it through any public members.
The first example will allow access to firstField, as you are creating a public getter/setter which sets it value;
If firstfield is only to be used within the example class, you can make it private i,e,
private bool firstfield;
I'm trying to develop an application on which I have an MDIParent and several MDIchilds. I would like to create a global variable on my MDIParent, and I want that variable to be accessible from its children.
How can I do that??
If Matthew Watson's answer isn't what you're after...
If you just want your "global" variable to be accessible to the children of a particular MDI parent form, then just use a regular instance property on it. The children will be able to access it through child.MdiParent.MyVariable (after casting MdiParent to the appropriate type). For example:
class ParentForm
{
public int MyVariable
{
return 1;
}
}
class ChildForm
{
public void MyMethod()
{
var parent = this.MdiParent as ParentForm;
foo = parent.MyVariable;
}
}
A quick note: it's generally best to avoid using "global" variables (i.e. static fields/properties) as much as possible. Keep all the different parts of your program's state confined to the appropriate context to reduce coupling. See the Law of Demeter.
A global variable in C# is effectively a static field or property.
So just add a public static property to MDIParent:
public static int MyGlobalInt
{
get
{
return 42;
}
}
That will be shared among ALL instances of MDIParent. If that's not what you meant, then it's not a global you want.
In my SharePoint 2010 c# / asp.net site, I have a class defined like
namespace PDF_Library.VisualWebPart1
{
public partial class PDF_Library : Usercontrol
{
public static PDF_Library current;
protected void Page_Load(object sender, EventArgs e)
{
current = (PDF_Library)this;
}
}
}
public static class Page_State
{
public static Page is_display()
{
return PDF_Library.current.Page; // didn't work...
}
}
It doesn't have a constructor.
How can I get the reference to the current instance of this class?
I tried something like this in the top
public static PDF_Library current;
Then in a function it had
current = (PDF_Library)this;
But that didn't work...
You need to understand that it does not work this way. Your question is tagged with asp.net - multi-user, multi-threaded environment where multiple instances of PDF_Library user control will be created all the time. It is absolutely uncertain which one of them will be hanging off PDF_Library.current. You need to rethink your design.
More on this: Page instance is disposed of when the request processing is finished. Normally this instance with all its controls and things such as Response, Request, Context etc will be set for garbage collection. Because you keep a reference to a UserControl instance in a static field, all these objects (including Page) will be kept in memory until this current reference is replaced with something else.
It is the fact that you used static in the function that was assinging current that this did not work. static is a method that is not tied to any instance of the class, therefor you can not use this.
Your only options are either make the method non-static or pass in a instance of the class as a parameter to the static function.
From what I can tell you are trying to create a "Singleton Pattern". See the link to the previous MSDN article for examples on how to create a singleton class.
This looks like it will have an instance. If the class is marked as static (which it doesn't appear to be) then you can just reference it by name "PDF_Library". Other wise, use ILSpy or reflector to look at the end result. I bet it has a constructor; just because you don't see one, doesn't mean it isn't there. Override the default ctor and set your instance there.
namespace PDF_Library.VisualWebPart1
{
public partial class PDF_Library : Usercontrol
{
public static PDF_Library Current;
public PDF_Library() : base() {
Current = this;
}
}
}
The problem you might be having with your Page_Load code is that it's being called too late in the lifecycle and that's why your reference call isn't working.
In almost all of my classes, I have a mixture of properties and internal class variables. I have always chosen one or the other by the rule "property if you need it externally, class variable if not". But there are many other issues which make me rethink this often, e.g.:
at some point I want to use an internal variable from outside the class, so I have to refactor it into a property which makes me wonder why I don't just make all my internal variables properties in case I have to access them externally anyway, since most classes are internal classes anyway it aren't exposed on an API so it doesn't really matter if the internal variables are accessible from outside the class or not
but then since C# doesn't allow you to instantiate e.g. List<string> property in the definition, then these properties have to be initialized in every possible constructor, so these variables I would rather have internal variables just to keep things cleaner in that they are all initialized in one place
C# code reads more cleanly if constructor/method parameters are camel case and you assign them to pascal case properties instead of the ambiguity of seeing templateIdCode and having to look around to see if it is a local variable, method parameter or internal class variable, e.g. it is easier when you see TemplateIdCode = templateIdCode that this is a parameter being assigned to a class property. This would be an argument for always using only properties on internal classes.
e.g.:
public class TextFile
{
private string templateIdCode;
private string absoluteTemplatePathAndFileName;
private string absoluteOutputDirectory;
private List<string> listItems = new List<string>();
public string Content { get; set; }
public List<string> ReportItems { get; set; }
public TextFile(string templateIdCode)
{
this.templateIdCode = templateIdCode;
ReportItems = new List<string>();
Initialize();
}
...
When creating internal (non-API) classes, what are your strategies in deciding if you should create an internal class variable or a property?
If I have a private variable that I find needs public access at a later point, I just create a property that uses it as it's private member, ex:
private List<string> listItems = new List<string>();
Public List<string> ListItems
{
get{return listItems;}
set{listItems = value;}
}
This allows you to create public access to the data, without having to refactor any code. It also allows you to initialize the data in the private member, and not have to do it in the constructor.
One more advantage is that any modifications to the data that you want to perform for anyone accessing the public property, can be done in the property's getter.
Even though VS2008 introduced Automatic Properties as a feature, I still prefer the VS2005 style of properties.