HOWTO: Use application global variables in VB.NET
Posted: 12/20/2004 10:16:25 AMBy: Comfortably Anonymous
Times Read: 16,353
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
While some purists of programming theory will adamantly oppose the use of application global variables, they are usually not the people in the trenches that have a project that must be completed yesterday. While you do need to limit your use of application-wide global variables to the absolute minimum (otherwise you can end up with some horribly splintered code), sometimes you just have to use a global variable accessible to the whole application or you’re going to have a massive mess on your hands from passing data back and forth between functions. (That’s pretty much the decision point on when to use a global variable – is the code going to be more or less understandable, thus maintainable, if you go ahead and use a global variable.)
An instance where I generally find that the use of a global variable is an “acceptable risk” is in a Windows Form application with multiple forms that all need to access the same array. Without using the global, you’d be stuck with passing an entire array between forms. This would be a terrible waste of time that introduces unnecessary complexity to your project. Just go ahead and create your global variable and tell the purists to go talk to the hand.
But, how do you go about creating a global variable? Where does the declaration go? That is the tricky question, but with a relatively simple solution. All you do is add a separate class to your application and declare your globals in that class as “Public Shared”.
Here’s an example in Visual Basic.NET:
Create a new project. This will create an empty project with a blank Windows Form with the name Form1.
Click on Project|Add Class. Give the new class a name like clsGlobal. This is where your global variables will live.
Click on Project|Add Windows Form, go with the default name of Form2 for this example. We’ll use this to show that global data modified in Form1 can be accessed from Form2.
clsGlobal:
Open the code for clsGlobal in the code editor. Add the following line between Public Class clsGlobal and End Class:
Public Shared test As String
Form1:
Open Form1 in the form designer. Add two buttons.
Double-Click Button1, add the following code to its event code:
clsGlobal.test = Now
Double-Click Button2, add the following code to its event code:
Dim frm2 As Form2
frm2 = New Form2
frm2.Show()
Form2:
Open Form2 in the form designer. Add one button.
Double-click Button1, add the following code to its event code:
MessageBox.Show(clsGlobal.test)
You now have a working example. Run the code.
Click Button1 on Form1 to set the current time in the global variable named test.
Click Button2 on Form1 to show Form2.
Move Form2 so that you can see both Form1 and Form2 at the same time.
Click Button1 on Form2, a messagebox will display the time and date when Button1 on Form1 was clicked.
Click Button1 on Form1 again, then click Button1 on Form2 – you will see the time stored in the global variable has updated!
This is the basics on how to use a global variable in VB.NET. Enjoy!
An instance where I generally find that the use of a global variable is an “acceptable risk” is in a Windows Form application with multiple forms that all need to access the same array. Without using the global, you’d be stuck with passing an entire array between forms. This would be a terrible waste of time that introduces unnecessary complexity to your project. Just go ahead and create your global variable and tell the purists to go talk to the hand.
But, how do you go about creating a global variable? Where does the declaration go? That is the tricky question, but with a relatively simple solution. All you do is add a separate class to your application and declare your globals in that class as “Public Shared”.
Here’s an example in Visual Basic.NET:
Create a new project. This will create an empty project with a blank Windows Form with the name Form1.
Click on Project|Add Class. Give the new class a name like clsGlobal. This is where your global variables will live.
Click on Project|Add Windows Form, go with the default name of Form2 for this example. We’ll use this to show that global data modified in Form1 can be accessed from Form2.
clsGlobal:
Open the code for clsGlobal in the code editor. Add the following line between Public Class clsGlobal and End Class:
Public Shared test As String
Form1:
Open Form1 in the form designer. Add two buttons.
Double-Click Button1, add the following code to its event code:
clsGlobal.test = Now
Double-Click Button2, add the following code to its event code:
Dim frm2 As Form2
frm2 = New Form2
frm2.Show()
Form2:
Open Form2 in the form designer. Add one button.
Double-click Button1, add the following code to its event code:
MessageBox.Show(clsGlobal.test)
You now have a working example. Run the code.
Click Button1 on Form1 to set the current time in the global variable named test.
Click Button2 on Form1 to show Form2.
Move Form2 so that you can see both Form1 and Form2 at the same time.
Click Button1 on Form2, a messagebox will display the time and date when Button1 on Form1 was clicked.
Click Button1 on Form1 again, then click Button1 on Form2 – you will see the time stored in the global variable has updated!
This is the basics on how to use a global variable in VB.NET. Enjoy!
Rating: (You must be logged in to vote)
Discussion View:
By: Comfortably Anonymous
Times Read: 2,955
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
By: Comfortably Anonymous
Times Read: 1,810
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
By: Comfortably Anonymous
Times Read: 3,291
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
By: Comfortably Anonymous
Times Read: 2,221
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
By: Comfortably Anonymous
Times Read: 2,093
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
By: Comfortably Anonymous
Times Read: 1,695
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
Replies:
RE: HOWTO: Use application global variables in VB.
Posted: 3/24/2005 8:18:10 PMBy: Comfortably Anonymous
Times Read: 2,955
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
thank you for making simple what so many other sources including Microsoft!!! --- can't
Rating: (You must be logged in to vote)
RE:
Posted: 3/25/2005 6:05:04 PMBy: Comfortably Anonymous
Times Read: 1,810
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
Thank You
Rating: (You must be logged in to vote)
UPDATE: Use application global variables in VB.
Posted: 3/28/2005 10:59:57 AMBy: Comfortably Anonymous
Times Read: 3,291
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
A minor update to the HOWTO on global variables:
This isn't absolutely needed, but it's still a good idea. Generally, a class is just a definition of how to 'instantiate' an object based on the class. More of a blueprint of an object than something you should use directly. Good programming practice says that you should 'instantiate' a class into an actual object before using it.
In truth, a non-instantiated class shouldn't work, but it seems to work just fine in VB.NET, which is actually what is happening in the original version of this HOWTO.
It's a bit mysterious what is going on by using the public shared variables in the non-instantiated class clsGlobals. (Without instantiating the class, we are basically using a 'ghost' object.) To do it correctly, with instantiated objects requires a small change to the example.
Let's just start over from the beginning and do it right:
Create a new project. This will create an empty project with a blank Windows Form with the name Form1.
Click on Project|Add Class. Give the new class a name like clsGlobal. This is where your global variables will live.
Click on Project|Add Windows Form, go with the default name of Form2 for this example. We’ll use this to show that global data modified in Form1 can be accessed from Form2.
clsGlobal:
Open the code for clsGlobal in the code editor. Add the following line between Public Class clsGlobal and End Class:
Public Shared test As String
Form1:
Right-click on Form1 in the Solution Explorer, select View Code. Right between "Windows Form Designer Generated Code" and "End Class", put the following:
Dim Globals As New clsGlobal 'Instantiate the object
Now, open Form1 in the form designer. Add two buttons.
Double-Click Button1, add the following code to its event code:
Globals.test = Now ' Note use of instantiated object name rather than class name.
Double-Click Button2, add the following code to its event code:
Dim frm2 As Form2
frm2 = New Form2
frm2.Show()
Form2:
Select Form2 in the Solution Explorer. Right-click and select View Code. Right between "Windows Form Designer Generated Code" and "End Class", put the following:
Dim Globals As New clsGlobal 'Instantiate the object
Now we have two separate objects, one instantiated as part of Form1, the other instantiated as part of Form2. Now we refer to the variable 'test' using the object name (Globals, aka: Form1.Globals.test and Form2.Globals.test) rather than the class name (clsGlobals). This is where the keyword "Shared" kicks in - it causes all instances of a class to share the same data. We have two separate instantiations of the same class, one called Form1.Globals, the other Form2.Globals. Without the word shared, each of the instantiated objects would contain a variable called 'test' with completely unrelated data in each. Changing the Form1.Globals.test would have no effect on Form2.Globals.test. However, since the keyword 'shared' is used in the class definition of the variable named 'test', all instances refer to the same data, thus we can use it as a global variable just like in the first HOWTO example, but with proper class instantiation this time.
Open Form2 in the form designer. Add one button.
Double-click Button1, add the following code to its event code:
MessageBox.Show(Globals.test) ' Note use of object name rather than class name
You now have a working example. Run the code.
Click Button1 on Form1 to set the current time in the global variable named test.
Click Button2 on Form1 to show Form2.
Move Form2 so that you can see both Form1 and Form2 at the same time.
Click Button1 on Form2, a messagebox will display the time and date when Button1 on Form1 was clicked.
Click Button1 on Form1 again, then click Button1 on Form2 – you will see the time stored in the global variable has updated!
Note that this works exactly the same as the first example. Just that we are not using the mysterious 'ghost object' clsGlobal, but are instantiated actual objects based on that class definition. If anyone knows any info about why the 'ghost object' even works at all, please post here. It's really got me intrigued, but I cannot find any explanation of it.
This isn't absolutely needed, but it's still a good idea. Generally, a class is just a definition of how to 'instantiate' an object based on the class. More of a blueprint of an object than something you should use directly. Good programming practice says that you should 'instantiate' a class into an actual object before using it.
In truth, a non-instantiated class shouldn't work, but it seems to work just fine in VB.NET, which is actually what is happening in the original version of this HOWTO.
It's a bit mysterious what is going on by using the public shared variables in the non-instantiated class clsGlobals. (Without instantiating the class, we are basically using a 'ghost' object.) To do it correctly, with instantiated objects requires a small change to the example.
Let's just start over from the beginning and do it right:
Create a new project. This will create an empty project with a blank Windows Form with the name Form1.
Click on Project|Add Class. Give the new class a name like clsGlobal. This is where your global variables will live.
Click on Project|Add Windows Form, go with the default name of Form2 for this example. We’ll use this to show that global data modified in Form1 can be accessed from Form2.
clsGlobal:
Open the code for clsGlobal in the code editor. Add the following line between Public Class clsGlobal and End Class:
Public Shared test As String
Form1:
Right-click on Form1 in the Solution Explorer, select View Code. Right between "Windows Form Designer Generated Code" and "End Class", put the following:
Dim Globals As New clsGlobal 'Instantiate the object
Now, open Form1 in the form designer. Add two buttons.
Double-Click Button1, add the following code to its event code:
Globals.test = Now ' Note use of instantiated object name rather than class name.
Double-Click Button2, add the following code to its event code:
Dim frm2 As Form2
frm2 = New Form2
frm2.Show()
Form2:
Select Form2 in the Solution Explorer. Right-click and select View Code. Right between "Windows Form Designer Generated Code" and "End Class", put the following:
Dim Globals As New clsGlobal 'Instantiate the object
Now we have two separate objects, one instantiated as part of Form1, the other instantiated as part of Form2. Now we refer to the variable 'test' using the object name (Globals, aka: Form1.Globals.test and Form2.Globals.test) rather than the class name (clsGlobals). This is where the keyword "Shared" kicks in - it causes all instances of a class to share the same data. We have two separate instantiations of the same class, one called Form1.Globals, the other Form2.Globals. Without the word shared, each of the instantiated objects would contain a variable called 'test' with completely unrelated data in each. Changing the Form1.Globals.test would have no effect on Form2.Globals.test. However, since the keyword 'shared' is used in the class definition of the variable named 'test', all instances refer to the same data, thus we can use it as a global variable just like in the first HOWTO example, but with proper class instantiation this time.
Open Form2 in the form designer. Add one button.
Double-click Button1, add the following code to its event code:
MessageBox.Show(Globals.test) ' Note use of object name rather than class name
You now have a working example. Run the code.
Click Button1 on Form1 to set the current time in the global variable named test.
Click Button2 on Form1 to show Form2.
Move Form2 so that you can see both Form1 and Form2 at the same time.
Click Button1 on Form2, a messagebox will display the time and date when Button1 on Form1 was clicked.
Click Button1 on Form1 again, then click Button1 on Form2 – you will see the time stored in the global variable has updated!
Note that this works exactly the same as the first example. Just that we are not using the mysterious 'ghost object' clsGlobal, but are instantiated actual objects based on that class definition. If anyone knows any info about why the 'ghost object' even works at all, please post here. It's really got me intrigued, but I cannot find any explanation of it.
Rating: (You must be logged in to vote)
DANGER - WARNING - Big Problem using with ASP.NET!
Posted: 4/6/2005 2:35:40 PMBy: Comfortably Anonymous
Times Read: 2,221
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
Just discovered a big huge problem when doing the "Public Shared trick" with ASP.NET! Do NOT use Public Shared with ASP.NET unless you need Application Global (Not Session Global) scope:
I had assumed that Public Shared would be localized (scoped) to a single ASP.NET session. I was very much wrong! Anything declared as Public Shared is accessible from ALL SESSIONS. Expect extremely unexpected behavior with your ASP.NET web app if declaring your variables as Public Shared and expecting them to be accessible across your entire application, but local to a single user.
Although I hate using untyped variables in ASP.NET, make sure that you use Session("VariableName") for your variables which should be accessible only to a single user (session) across the entire application.
Although, I have come up with somewhat of a compromise to use Typed Session Variables with ASP.NET. It's not perfect, but it's better than nothing, and still allows and enforces the use of typed variables, but all the nice Intellisense auto-complete does not work with it, so your design errors turn into runtime errors rather than designtime errors. :(
I am at work right now, so will write up how to do this tonight with the separate title "HOWTO: Typed Session Variables in ASP.NET" under this current (Programming: Visual Basic.NET) topic.
I had assumed that Public Shared would be localized (scoped) to a single ASP.NET session. I was very much wrong! Anything declared as Public Shared is accessible from ALL SESSIONS. Expect extremely unexpected behavior with your ASP.NET web app if declaring your variables as Public Shared and expecting them to be accessible across your entire application, but local to a single user.
Although I hate using untyped variables in ASP.NET, make sure that you use Session("VariableName") for your variables which should be accessible only to a single user (session) across the entire application.
Although, I have come up with somewhat of a compromise to use Typed Session Variables with ASP.NET. It's not perfect, but it's better than nothing, and still allows and enforces the use of typed variables, but all the nice Intellisense auto-complete does not work with it, so your design errors turn into runtime errors rather than designtime errors. :(
I am at work right now, so will write up how to do this tonight with the separate title "HOWTO: Typed Session Variables in ASP.NET" under this current (Programming: Visual Basic.NET) topic.
Rating: (You must be logged in to vote)
RE: HOWTO: Use application global variables in VB.
Posted: 4/13/2005 9:28:55 AMBy: Comfortably Anonymous
Times Read: 2,093
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
As I understand it, using public shared is not taking improper advantage of the "ghost class", but rather using it for what it was intended. I believe it was explicitly created to produce functions like those provided in the programming languages which require no instantiation to use (such as INSTR or SIN). I use it regularly for such purposes (although it hadn't occurred to me this might cause a problem in ASP applciations, so thanks for pointing that out!). In the secenario provided, it might be more akin to the constant of PI except, of course, you may want to change the value.
Rating: (You must be logged in to vote)
RE:
Posted: 4/22/2005 8:55:14 PMBy: Comfortably Anonymous
Times Read: 1,695
Likes: 0 Dislikes: 0
Topic: Programming: .NET Framework
Thank you for the help, this was useful in completing part of my last program for a class.
God Bless
God Bless
Rating: (You must be logged in to vote)