C# and Variable Scope in Winforms - c#

Within a Winform app, I would like data in an instantiated class to be accessible by multiple form controls.
For example, if I create Class Foo, which has a string property of name, I'd like to instantiate Foo a = new a() by clicking Button1, and when I click Button2, I'd like to be able to MessageBox.Show(a.name). There may be multiple instances of Foo, if that matters at all.
What is my best option for being able to use class instances in such a way?

A private field or property of a class satisfies the requirement - such field can be accessed by all methods of the class.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
foo a;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
a = new foo();
a.name = "bar";
}
private void button2_Click(object sender, EventArgs e)
{
if (a != null && a.name != null)
MessageBox.Show(a.name);
else
MessageBox.Show("");
}
}
public class foo
{
public string name { get; set; }
public foo() { }
}
}
If you want this variable to be accessible to other forms you'd need to make it public (preferably as property) - C# winform: Accessing public properties from other forms & difference between static and public properties

maybe you just want a static class

Winforms are nothing but some graphical elements backed by code. The code can own/create objects just like regular 'non-winform' code. The same scoping rules apply.
My guess if yours is more a problem of 'how does my form access shared state defined outside of it'? Create a static class, or have a setter on the class of your form that other code can use to set this shared state.

A form you create is just another class, derived from Form. A class exists in a given namespace, so you just need to create your Foo class in a namespace shared by your application's forms.
If a class is shared by multiple forms, then usually you'd separate out that class into a separate file.

Jon Skeet [C# MVP]
Guest Posts: n/a
2: May 15 '07
re: Application variables in csharp.
On May 15, 12:04 pm, Control Freq
wrote:
Quote:
Still new to csharp. I am coming from a C++ background.
>
In C++ I would create a few top level variables in the application
class. These are effectively global variables which can be accessed
throughout the application because the application object is known.
>
What is the csharp equivalent of this practice?
I can't seem to add variables to the "public class Program" class and
get access to them from other files.
>
I am probably missing something obvious.
Basically you want public static fields (or preferably properties).
An alternative to this is a singleton:
http://pobox.com/~skeet/csharp/singleton.html
Jon
When in doubt, find something signed by John Skeet. Found on: http://bytes.com/topic/c-sharp/answers/646865-application-variables-csharp

Related

How can I move code to create a list into a separate class and then call it

Newby c#/asp.net question here. I am creating a website with .aspx pages.
Within a method I have created a list and added items to it as shown below:
var footballTeams = new List<string>();
footballTeams.Add("Arsenal");
footballTeams.Add("Aston Villa");
footballTeams.Add("Bournemouth");
footballTeams.Add("Brentford");
footballTeams.Add("Brighton & Hove Albion");
footballTeams.Add("Chelsea");
However, I want to move this code into its own separate class - so it is easier to update the teams rather than have to go deep into code.
How would I code this in a class and then be able to call and use the list from another class.
I have tried creating a new folder called App_Code. And then putting a dummy method in it as shown below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace FootballResultPredictor.App_Code
{
public class Class1
{
public static String MyMethod()
{
string myString = "test";
return myString;
}
}
}
However when I try to call the method from the other class, it just can't seem to find it at all as shown here:
Below is the file structure:
I am trying to call a method in Class1.cs from StartNewSeason.aspx
Looking quickly at your code, I have some comments.
-Don't put your new class in a separate folder.
-This code is wrong: string a=myMethod();
because you can't call a method before you have an instance (new...) of a class unless the class is a static class, which is not the case here.
-Coding string b=Class1.MyMethod(), is better, but still wrong, since Class1 is the name of the class not the name of the object.
At this point, I guess the concept of the class and the class object are somewhat not very clear to you.
I suggest that you review this fundamental concept as it is the core of Object Oriented Programming. Also using ASP.NET at this point of your learning path is highly not advisable, I highly recommend that you get to learn OO fundamentals through C# console applications or Windows Forms. These two frameworks, are much simpler to deal with.
When you create a class (of .cs type) file under the same solution in VS it would have a namespace and a class definition. If the class is not static, you refer to it as (other ways can be used as well):
myClassName ObjectName = new myClassName();
The namespace can be specified if the class is in a different project, like new NameSpace2.myClassName, but this is not the case here.
Only after you create an instance (an object) of the non-static class, you can use the object and its method using the ObjectName (not the myClassName). For exmaple:
ObjectName.MethodName();
Back to the program at hand, here is one way to have a separate class handle the list. There are many ways to do this, this way provides validation and allows you to iterate over the list items. Let me know if this is not clear.
The new class is here:
//using System;
//using System.Collections.Generic;
//using System.Data;
public class FootballTeams
{
public List<string> footballTeams = new List<string>();
public FootballTeams()
{
//initialize the list
this.AddFootballTeam("Arsenal");
this.AddFootballTeam("Aston Villa");
this.AddFootballTeam("Bournemouth");
this.AddFootballTeam("Brentford");
this.AddFootballTeam("Brighton & Hove Albion");
this.AddFootballTeam("Chelsea");
}
//Method to add a new team
public void AddFootballTeam(string parmTeam)
{
//validate input
if (string.IsNullOrWhiteSpace(parmTeam))
{ throw new NoNullAllowedException("Error:Team name is empty"); }
if (footballTeams.Contains(parmTeam))
{ throw new DuplicateNameException(); }
//if valid add the name to the list
footballTeams.Add(parmTeam);
}
}
A sample usage of the above class is:
var _t = new FootballTeams();
try
{
_t.AddFootballTeam("Ringers");
}
catch (Exception _ex)
{
Console.WriteLine(_ex.Message);
return;
}
foreach (var _team in _t.footballTeams)
{
Console.WriteLine(_team);
}

C# Windows Form Initialize

I have a windows form app with 2 forms, and I need to press a button in form one to go to form 2(this is done already) then form 2 will be able to create an object using the add customer method to add to the system. My question is:
1)if I create an Object in Form 2, how could other forms(form3,form4 etc.) have access to this object? As far as I have learned, I can only call the method through an object.
2)if I created an object in Form1, and other forms inherited from form 1, will this object still work in other forms?
3)Objects can be inhereited or not? is this a good practice in real world?
4) How to allow different forms using one object different method?
A static field or property as suggested in zdimension's answer is possible, of course, but it shouldn't be your first option. There are lots of ways to pass data between forms, and it depends on your application which one is best. For example, one way of doing it is:
class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public AirlineCoordinator Coordinator {get; set;}
...
}
class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public AirlineCoordinator Coordinator {get; set;}
private void Form1_Load(object sender, EventArgs e)
{
this.Coordinator = new AirlineCoordinator(...);
...
}
...
private void ShowForm2Button_Click(object sender, EventArgs e)
{
using(var form2 = new Form2())
{
form2.Coordinator = this.Coordinator;
form2.ShowDialog(this);
}
}
}
In this hypothetical example, Form1 has a button ShowForm2Button; clicking on this button shows Form2 using the same AirlineCoordinator as is used by Form1.
The usual way to make something available to "everyone" is to use a static field, like this:
public class GlobalStuff
{
public static MyType SomeVariable;
}
Here, the GlobalStuff obviously only ever contains global things, so you could consider making it static too to indicate it will never be instanciated.
Here's what MSDN say about it:
Use a static class as a unit of organization for methods not associated with particular objects. Also, a static class can make your implementation simpler and faster because you do not have to create an object in order to call its methods. It is useful to organize the methods inside the class in a meaningful way, such as the methods of the Math class in the System namespace.

c# Calling method in partial call from another class

I'm making c# app where I need to access method in partial class from another class.
To be more specific I want to add items to listview from class that is different from partial class but in same namespace.
I tried like this:
public partial class Aa : Form
{
public static void UpdateListView(string[] array)
{
if (ProcessNetUsageList.InvokeRequired)
{
ProcessNetUsageList.Invoke(new Action<string[]>(UpdateListView), array);
}
else
{
ListViewItem item = new ListViewItem(array[0]);
for (int i = 1; i < 4; i++)
item.SubItems.Add(array[i]);
ProcessNetUsageList.Items.Add(item);
}
}
}
and then access it from another class like:
class Test
{
test()
{
ProgramName.Aa.UpdateListView(someArray);
}
}
But its giving an error because static method can only access static variables,and my listview isnt static(i created that listview in vs designer).
If i remove static keyword from method in partial class then i cant access it.I tried to create instance of partial class but without success.Any idea is welcome
note:Im using Invoke in my UpdateListView method because later that will be running on new thread
The nature of an object-oriented language is that objects don't have universal access to modify other objects. This is a good thing.
You've provided relatively little code so it's hard to provide a perfect answer here, but there are a few paradigms that resolve this issue.
One is to pass the instance to your test class, like this:
class Test
{
test(ProgramName.Aa form)
{
form.UpdateListView(someArray);
}
}
Or, if class test actually contains the ListView, you can pass that to a static method in Aa.
class Test
{
ListView someListView;
test()
{
ProgramName.Aa.UpdateListView(someListView, someArray);
}
}
Ultimately, you should think about the logical relationship between these objects to determine how these objects should communicate.
Remove the static keyword from UpdateListView, as you have done before. In test(), you need to instantiate Aa before you access UpdateListView.
Aa temp = new Aa()
You can then access the method by using
temp.UpdateListView(someArray);

Is it possible to have Global Methods in C#

So I have a static class lets say its called Worker, and lets say
I have a method inside it called Wait(float f) and its all public so I can acess it anywhere like so:
Worker.Wait(1000);
Now what I am wondering is there any way I can define some kind of unique
special methods so I could just do it short like this:
Wait(1000);
(Without having it in the class I would use it in) ?
With C# 6 this can be done. At the top of your file you need to add a using static Your.Type.Name.Here;.
namespace MyNamespace
{
public static class Worker
{
public static void Wait(int msec)
{
....
}
}
}
//In another file
using static MyNamespace.Worker;
public class Foo
{
public void Bar()
{
Wait(500); //Is the same as calling "MyNamespace.Worker.Wait(500);" here
}
}
No, you cannot have methods that are not part of a class in C#.
No, you can not, Methods belong to a class, if you do Wait(1) is because you are in a class where that method is defined (or is the parent class)
Edit...
As commented that was true up to C# 5, this can be done in C# 6 now it can be done importing statically some classes...
take a look at Scott Chamberlain"s answer here and link to MSDN

access a Form1 public function from static class inside Form1

When writing this post i was checking all questions asked with related subject
and couldent find a simple answer to this Newbs C# issue
i would like ... if i may , to have as much as it can be a well-explaind answer (Please!)
i made a public static class
public static class MyLoadedBtmpToolBox
{
public static string FnameToLoad;
public static bool PutLoadedByteArrInPicbox;
public static string[] LoadedRefrnce;
public static int SourceX_Loaded, SourceY_Loaded, RectWidth_Loaded, RectHeight_Loaded;
---> public static int tst = Str2Int(LoadedRef[0]);
public static byte[] LoadedByteArr;
}
this calss as usually does by default, is within the main form i am using
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.IO;
using System.Security.Cryptography;
using WindowsInput;
namespace MyScrCupTry1
{
public partial class MyForm1 : Form
{
public static class MyLoadedBtmpToolBox
{
public static int testStr2Int = Str2Int("100");
}
public int Str2Int(string STR)
{
int strInt = Convert.ToInt32(null);
if (isntEmpty(STR))
{
strInt = Convert.ToInt32(STR);
}
else
{
MessageBox.Show("theString " + STR + " is Null");
}
return strInt;
}
}
i can't assing the testStr2Int a value , by using my public "helper Method" Str2Int() from the main form
i am Getting Error :
Error 1 An object reference is required for the non-static field, method, or property 'MyScrCupTry1.MyForm1.Str2Int(string)' G:\RobDevI5-Raid-0\Documents\Visual Studio 2010\Projects\WindowsFormsApplication2\WindowsFormsApplication2\MyForm1.cs 95 45 MyScrCuptry1
What is the right way for accessing Main Form Public elemets from a static Class
if it is possible / (not illegal)...
ReEditing
after Those two answers ...
I tried to implement
the code from first answer without expected results i guess i didn't know the right code structure with override OnLoad(..) thing ...
BUT !
i have turnd the method Str2Int(STR) from public into public static
so now elements from the form itself still have access (i am surprised) to Str2Int()
and from the static Class I Can Access it too....
and its all thanks tp making it into static too ,
am i missing somthing else is there "hidden" drawback when changing Str2Int() from public into public static ?
The point of static code is that belongs to itself, rather than any other object. For this to be true, when you set something as static, everything that depends on it must also be static!
This is what your error message is trying to tell you. You are declaring something as static, but in the computation of that static, you are using something that is not static. Str2Int is not tagged as static, so that is an immediate problem, and it's possible that LoadedRef is also not static. I am half-sure you actually meant to use LoadedRefrnce there, in which case you're fine, but since you spelled nothing correctly I can't be sure!
Check this page for an explanation of the static keyword, also please make more of an effort to read up on C# coding conventions - this makes it much easier for people to read your code when you ask for help like this!
Expanding upon the edits above:
The 'drawback' to making code static is that it pretty much instantly makes everything it is a part of untestable. The idea behind unit testing is to have all of your code broken out into totally replaceable parts, so they can be tested separately and moved out separately (if need be). By making a bunch of code static, you are essentially welding it to any other code it might be a part of. In your own example, by making Str2Int() public static, everything that uses Str2Int() is now untestable!
Static code is, generally speaking, a vice that you should attempt to avoid as much as possible. There are places where you can't, and if you are just starting to learn really the biggest focus is just getting something working. But be ready to look back on this code and go cold at how you could've ever written something so bad in a few years, when you are more experienced and confident in your skills.
add Form object to static class, like this :
public static class MyLoadedBtmpToolBox
{
public static Form MainForm {get;set;}
public static int testStr2Int = MainForm.Str2Int("100");
}
and from the Form :
public partial class MyForm1 : Form
{
private override OnLoad(..){
base.OnLoad(...);
MyLoadedBtmpToolBox.MainForm =this;
}
}
This design is fragile by itself, as you has to gurantee that MyForm property is intialized before it's used to call ..testStr2Int = MainForm.Str2Int("100")...
So, considering that testStr2Int is public, may be intialization of it you can do in Form too and not in static class.

Categories