-
Sep 13th, 2017, 01:58 PM
#1
Thread Starter
Lively Member
HOw do I create a variable that will be visible over several forms?
The variable, X, needs to be incremented from three forms in one project.
Each form will have a Next button to do the deed.
Of course if I dim the integer on any form it is active only for that form.
1 project, three forms, X should be visible to all.
-
Sep 13th, 2017, 02:20 PM
#2
Re: HOw do I create a variable that will be visible over several forms?
Create a class object, and add X to it and declare it Shared.
You can then access it by the ClassName.X from each form, SharedData.X, for instance.
Code:
Public Class SharedData
Public Shared X As Integer
End Class
Or, add a Module and add X to it, declaring it Public.
You can then access it by the name X in each form.
Code:
Module SharedData
Public X As Integer
End Module
Since you don't have to specify the Module name, some prefer not using a module as it "pollutes" the global names space in your application.
Last edited by passel; Sep 13th, 2017 at 06:20 PM.
-
Sep 13th, 2017, 02:39 PM
#3
Re: HOw do I create a variable that will be visible over several forms?
personally I would use my.settings
my.settings.x += y
-
Sep 13th, 2017, 03:14 PM
#4
Thread Starter
Lively Member
Re: HOw do I create a variable that will be visible over several forms?
Nice, Very nice....
I used the module.
Thanks
-
Sep 13th, 2017, 03:16 PM
#5
Thread Starter
Lively Member
Re: HOw do I create a variable that will be visible over several forms?
Does this require a Dim statement or does it dim it?
-
Sep 13th, 2017, 03:20 PM
#6
Re: HOw do I create a variable that will be visible over several forms?
It requires "Public" ... that's used instead of "Dim" Dim by default I think makes variables private, so you need to specify a larger scope of either Friend or Public.
-tg
-
Sep 13th, 2017, 03:55 PM
#7
Addicted Member
Re: HOw do I create a variable that will be visible over several forms?
Any of the above will work but I just prefer using "Public" in the startup form on a simple app or in a module if I have "global" functions/subs that are better organized in a module. Purists will rant and rave about global variables but unless you're working with a team and people could accidentally tromp on your vars, it really doesn't matter (Unless its you doing the tromping).
Its a good idea to look up variable scope on google though. Unless you're familiar with the different scope declarations you WILL run into trouble. Most especially between "Dim" or "Private" (same things) and larger scopes. You can legitimately have two variables with identical names when they have two different scopes and that can confuse the heck out of the uninitiated.
-
Sep 13th, 2017, 04:16 PM
#8
Re: HOw do I create a variable that will be visible over several forms?
Originally Posted by pmeloy
Any of the above will work but I just prefer using "Public" in the startup form on a simple app or in a module if I have "global" functions/subs that are better organized in a module. Purists will rant and rave about global variables but unless you're working with a team and people could accidentally tromp on your vars, it really doesn't matter (Unless its you doing the tromping).
The biggest problem with global vars isn't that they exist... they are useful... at times. The biggest problem with them is the same problem with things like On Error Resume Next or DoEvents, and other techniques that tend to be frowned upon - they are misused and abused for the wrong reason. If you've got 50 global vars... that might (might) be a sign you've got problems. I'm not going to say it's a definitive indicator, just a potential one. Sometimes it's the best solution, sometimes not. Use it because it's the right solution, don't use it just for the sake of using it.
Originally Posted by pmeloy
Its a good idea to look up variable scope on google though. Unless you're familiar with the different scope declarations you WILL run into trouble. Most especially between "Dim" or "Private" (same things) and larger scopes. You can legitimately have two variables with identical names when they have two different scopes and that can confuse the heck out of the uninitiated.
Oh heck yeah that... I've gotten burned by that a few times trying to support someone else's code. YEah, that's always fun (no it's not).
-tg
-
Sep 13th, 2017, 04:50 PM
#9
Re: HOw do I create a variable that will be visible over several forms?
In the same vein as techgnome's answer:
I prefer having one "application state" object that is referenced by all three forms. This is conceptually identical to having a Module, though you have to write a few more lines of code to support it. Since it's an object reference, if one form changes a value, that value is visible to all forms. I can add events and other mechanisms to notify each Form when another changes it.
You can do those things with Modules, and many people do. For hobbyists and many professionals, that's pretty much the end of the discussion.
But my professional experience is my life got better when I quit using Modules. I could try and explain why over pages, but at this point it's a lot of "gut feeling". If you ever want to do unit testing, you'll have to wean yourself off static state at some point anyway. I think it's better to treat Modules as "a thing I use under the right circumstances".
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Sep 15th, 2017, 01:29 AM
#10
Re: HOw do I create a variable that will be visible over several forms?
Originally Posted by Sitten Spynne
I prefer having one "application state" object that is referenced by all three forms. This is conceptually identical to having a Module, though you have to write a few more lines of code to support it.
Many people don't know or realise it but you already have such an object accessible via My.Application. You can declare a property in the same file as you handle application-level events, e.g. Startup and UnhandledException, and then access those properties via My.Application. For those who aren't aware, you can open that code file by opening the Application page of the project properties and clicking the View Application Events button. If you want to keep that code file just for events then you can always create another partial class in another code file, although I don't personally see the point in that.
I'm not sure how testable that option is though. Never tried.
-
Sep 15th, 2017, 08:25 AM
#11
Thread Starter
Lively Member
Re: HOw do I create a variable that will be visible over several forms?
Originally Posted by jmcilhinney
I'm not sure how testable that option is though. Never tried.
I prefer to protect my testables and keep them private ( :
-
Sep 15th, 2017, 09:21 AM
#12
Re: HOw do I create a variable that will be visible over several forms?
Originally Posted by GarySut
I prefer to protect my testables and keep them private ( :
I'm not going to make any jokes about members.
-
Sep 15th, 2017, 10:18 AM
#13
Re: HOw do I create a variable that will be visible over several forms?
Let's run through a quick summary so I can reference this post in the future.
Forms are just classes. The way classes communicate with each other is via methods and properties. Someone out there is saying, "But what about events?" and the answer is events are fancy methods. (Think about it.) If you want many forms to be able to share information, you have to make methods and properties that each form is able to see.
One of the things people stumble on is for other things to see a method or property, you have to use the Public keyword. If you use any other keyword, then you need to memorize the VB Language Reference to understand when that means Public. I'm not going to say "public methods" or "public properties" any more from here on out, because unless I say otherwise that's what I mean.
Modules
The quick and dirty way is to use a Module. Properties and methods in a Module are "visible" to everything in the project. You don't have to worry about changing any existing Forms when you use a Module, you only have to start using it.
Code:
Public Module SomeModule
Public Property SomeNumber As Integer
End Module
Class Form1
Sub Form1_Load(...) Handles ...
SomeModule.SomeNumber += 1
Dim childForm As New Form2()
childForm.Show()
End Sub
End Class
Class Form2
Sub Form2Load(...) Handles ...
SomeModule.SomeNumber += 1
MessageBox.Show(SomeModule.SomeNumber.ToString())
End Sub
End Class
Keep in mind there's only one "copy" of Module variables. So if I wanted Form1 and Form2 to have a different SomeNumber than Form3 and Form4, I couldn't. I'd have to make a different property. But nothing would stop Form1/Form2 from accidentally modifying the wrong variable. That tends to be why professionals frown at Modules: when you put every variable in a place where everything in the project can access it, it's easier to make bad mistakes.
Shared Classes
These are basically Modules. If you make a class with only Shared properties and methods, those can be accessed from anything else just like Modules. The only difference between this approach and Modules is so subtle it's not worth talking about.
Classes
Most professionals use some variation of "not-Shared, not-Module" classes. We call them "instances" since that's easier to type.
Very new developers are opposed to making instance classes. There is a common belief that it is much harder to use them than Modules. Experts do not tend to agree with this view.
The extra complexity of instances is someone has to create the instance, and each Form that wants to see its methods and properties needs to have a variable that will "reference" the instance. Here is how the Module example might be changed to use an instance class:
Code:
Public Class SomeClass
Public Property SomeNumber As Integer
End Module
Class Form1
' The "New" keyword creates instances.
Private _myState As New SomeClass()
Sub Form1_Load(...) Handles ...
_myState.SomeNumber += 1
Dim childForm As New Form2(_myState)
childForm.Show()
End Sub
End Class
Class Form2
Private _myState As SomeClass
' Sub New() is what the "New" keyword looks for.
Public Sub New(ByVal sharedState As SomeClass)
' This line is auto-generated by Visual Studio, do not add anything before it.
InitializeComponent()
' Add anything you want Sub New() to do after InitializeComponent(). I mean it.
_myState = sharedState
End Sub
Sub Form2Load(...) Handles ...
_myState.SomeNumber += 1
MessageBox.Show(_myState.SomeNumber.ToString())
End Sub
End Class
Obviously it got bigger. I didn't promise it was "just as complex" to use instances. Instead I argue it's "worth the complexity".
To make an instance, you have to use the "New" keyword. It will call one of the type's Sub New() methods. If you didn't write any of those, one is automatically generated. Since Form1 is the "main form" in this example, it uses New to create the SomeClass instance that the forms will share.
We need to make sure Form2 sees the same object as Form1. So Form1 needs a way to give the object to Form2. I chose to add a Sub New() to Form2 that asks for the object as a parameter. Forms are special and have some magic code you don't usually see. Part of that magic is every Sub New() is supposed to call the InitializeComponent() method. Usually if you make a Sub New() in a Form, Visual Studio auto-generates this for you. If it doesn't, you'll be reminded quickly because none of your controls will be created when you run the form!
So Form1 gives the SomeClass instance to Form2 when it uses New to create the Form2 instance. When Form2 displays, it should display a message box that says "2". This is because SomeClass.SomeNumber starts with the value 0. When Form1 displays, it changes SomeNumber to 1. When Form2 displays, it changes SomeNumber to 2 then displays it.
Why do we bother? Well, now there are as many copies of SomeNumber as we care to make. Form1 and Form2 don't NEED to share the object. This code would give Form2 a unique instance of SomeClass:
Code:
Dim childForm As New Form2(New SomeClass())
That's usually not what you want. So keep in mind, every time you say "New", you're getting a different copy. Don't use it unless you aren't trying to share information between two forms.
Some people don't like messing with Sub New() and instead use properties:
Code:
Public Class SomeClass
Public Property SomeNumber As Integer
End Module
Class Form1
Private _myState As New SomeClass()
Sub Form1_Load(...) Handles ...
_myState.SomeNumber += 1
Dim childForm As New Form2()
childForm.State = _myState
childForm.Show()
End Sub
End Class
Class Form2
Public Property State As SomeClass
Sub Form2Load(...) Handles ...
State.SomeNumber += 1
MessageBox.Show(State.SomeNumber.ToString())
End Sub
End Class
There are reasons why you might choose this instead of Sub New(), and there are reasons you might choose Sub New() instead. I don't think understanding those distinctions is as important as understanding they are both how you share references between classes.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Sep 15th, 2017, 10:23 AM
#14
Re: HOw do I create a variable that will be visible over several forms?
Originally Posted by jmcilhinney
[...]
I'm not sure how testable that option is though. Never tried.
It is "less testable" though it is "better than Modules/Shared types".
MyApplication is a type that gets created as part of the VB application framework. That means one might not be created and wired up to the My.Application property when you are running unit tests, since they are generally a separate console .exe or a .dll consumed by a test runner. Even if it is properly wired up, it's wired up ONCE. That means every test using it has to be careful to reset it to some "default" state before proceeding. That's a very bad thing if you use parallel execution in MSTest.
And that's just talking properties. You can't substitute a different MyApplication class in for TestA, or if you can you have to remember to reset it to the "normal" one before running TestB. That means you can't easily override/mock any methods you implement within it.
In short, "an instance class referenced by a Shared property" has the same problems as "a Module" in terms of testability, even though it's more flexible. You want every test to be a self-contained program that cannot be affected by any other test. Any Shared property violates that.
(I made a separate post because it distracts from the last one.)
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Oct 5th, 2017, 09:31 PM
#15
Thread Starter
Lively Member
Re: HOw do I create a variable that will be visible over several forms?
I am not going to try to figure out all these comments but suffice it to say that I was able to glean the solution from the messages and it is working quite well.
Special thanks to all.....
-
Oct 6th, 2017, 08:59 AM
#16
Re: HOw do I create a variable that will be visible over several forms?
Originally Posted by Sitten Spynne
Let's run through a quick summary
It's good to get sufficient irony in your diet. A lack of irony tends to make a person lethargic.
My usual boring signature: Nothing
-
Oct 6th, 2017, 10:26 AM
#17
Re: HOw do I create a variable that will be visible over several forms?
A real discussion takes a book chapter, 4-6 pages, and an example application.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Oct 10th, 2017, 09:44 PM
#18
Thread Starter
Lively Member
Re: HOw do I create a variable that will be visible over several forms?
I wonder what you are thinking but I achieved it declaring variables in a module as suggested here.
It was so easy that my first year VB class understood and are using it in their projects.This is a course for non-computer science students.
Did I miss something?
-
Oct 11th, 2017, 07:55 AM
#19
Re: HOw do I create a variable that will be visible over several forms?
Not really. The parts I left out are the parts experts argue about.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Oct 11th, 2017, 11:32 AM
#20
Re: HOw do I create a variable that will be visible over several forms?
Globals have their place. That's why they exist. The key point that should be passed along is that this is not a simple subject, and there is considerable debate over best practices.
In programming, there are many ways to solve most problems. You have found one way to solve the problem you had, and others have also been suggested. Which one is best is likely not a question that can be definitively answered in any particular situation until the situation, and all the costs (which can be quite subtle) are well understood. So, you should just be aware that there is debate around globals....but sometimes...they are the right tool for the job.
My usual boring signature: Nothing
-
Oct 11th, 2017, 11:39 AM
#21
Fanatic Member
Re: HOw do I create a variable that will be visible over several forms?
KPMC,
The My.Settings thing is new to me. I have used modules for global variables and frankly I am not that fond of them or their usage. Could you, perhaps, provide me with some information so that I can understand what this is and exactly what it does? It truly looks interesting.
-
Oct 11th, 2017, 11:51 AM
#22
Re: HOw do I create a variable that will be visible over several forms?
Could you, perhaps, provide me with some information so that I can understand what this is and exactly what it does? It truly looks interesting.
I view the settings as a type of global variable. Basically the settings are stored in a config file "app.config" To add them double click on "My Project" then "Settings" You will see where you can name the 'variables' and assign a type to them.
To call them in your app, you simply go:
Code:
Dim MyValueFromSettings As String = My.Settings.VarName '(obviously matching the types)
You can also store the values and the app will preserve the settings
Any Class can use the settings Vars.
Many devs dont like to use them for various reasons, I use them mostly for connection strings (Very useful to build connection strings for manual declarations)
I am sure others will chime in with their 2 cents and a complete dissertation.
Last edited by kpmc; Oct 11th, 2017 at 12:51 PM.
-
Oct 11th, 2017, 11:56 AM
#23
Re: HOw do I create a variable that will be visible over several forms?
There are two important points to be aware of with My.Settings:
1) This is a type of storage, so it is like a variable that will retain settings between runs of the program. That's more than global. It also means that it will take up a certain amount of memory even when the program is not running....like any type of persistent storage.
2) Items in My.Settings are stored as plain text. Anybody can see/alter them with a text editor and minimal knowledge. That's something you need to be aware of, as you would need to encrypt anything sensitive.
My usual boring signature: Nothing
-
Oct 11th, 2017, 12:02 PM
#24
Re: HOw do I create a variable that will be visible over several forms?
2) Items in My.Settings are stored as plain text. Anybody can see/alter them with a text editor and minimal knowledge. That's something you need to be aware of, as you would need to encrypt anything sensitive.
This is a good point when storing connection strings. If security is a concern you will want to encrypt any passwords to the DB.
As for the first point, I can't imagine an instance where that could actually become a problem.
-
Oct 11th, 2017, 12:04 PM
#25
Re: HOw do I create a variable that will be visible over several forms?
Size? Yeah, I really doubt that is an issue anybody need worry about.
My usual boring signature: Nothing
-
Oct 11th, 2017, 12:07 PM
#26
Re: HOw do I create a variable that will be visible over several forms?
Universal Variable maybe? ...hmm maybe more of a Galactic Variable...
-
Oct 11th, 2017, 12:15 PM
#27
Re: HOw do I create a variable that will be visible over several forms?
Personally I think settings should be used for what they are, settings that needs to be persisted between runs. ConnectionStrings are a good use. So are user settings, like turning things on and off, or colors. But using them as "global" variables i think is stretching it a bit far. If you need a global, use a global. To further that, I'd also go far as saying if you have a global that is also persisted between app runs, you load it at the beginning, use it during the run, then save it once at the end. But that's my 2 cents (sorry no dissertation this time.)
-tg
-
Oct 11th, 2017, 12:17 PM
#28
Re: HOw do I create a variable that will be visible over several forms?
Originally Posted by Shaggy Hiker
Size? Yeah, I really doubt that is an issue anybody need worry about.
Until someone tried to stuff an entire typed dataset into a setting...
Originally Posted by kpmc
Universal Variable maybe? ...hmm maybe more of a Galactic Variable...
Not quite that far, more like solar system... Universal would be web.config and Galactic would be on the order of Machine.Config.
-tg
-
Oct 11th, 2017, 12:36 PM
#29
Re: HOw do I create a variable that will be visible over several forms?
Until someone tried to stuff an entire typed dataset into a setting...
Note to all... don't do this...
-
Oct 11th, 2017, 12:57 PM
#30
Re: HOw do I create a variable that will be visible over several forms?
Originally Posted by techgnome
Until someone tried to stuff an entire typed dataset into a setting...
-tg
Sure glad you went there. After seeing my post quoted, I realize that there are much worse directions it could have gone.
My usual boring signature: Nothing
-
Oct 11th, 2017, 01:03 PM
#31
Re: HOw do I create a variable that will be visible over several forms?
This is a great forum, just sayin...
-
Oct 11th, 2017, 01:09 PM
#32
Re: HOw do I create a variable that will be visible over several forms?
Bleh.
In the professional community:
Using Modules and global variables is the rough equivalent of using a shaving brush to brush your teeth. Functional, but not seen as the best.
Deciding to use My.Settings instead of Modules is like stating, "A shaving brush is the wrong tool for dental hygiene. I'm going to use sandpaper instead." Now you're using a tool to do a job outside its designed task.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Oct 11th, 2017, 01:28 PM
#33
Re: HOw do I create a variable that will be visible over several forms?
The way that I see it, I could go upstairs, open the cabinet, get the 'right' tool, load it up, clean it, buy a new bag for it to carry it with me every where i go... or grab the sand paper that was laying on the floor that was already provided and produce exactly the same outcome.
-
Oct 11th, 2017, 02:31 PM
#34
Re: HOw do I create a variable that will be visible over several forms?
And the reason there's an "expert" argument here is some people are skeptical "a shaving brush" and "sandpaper" do the same thing to your teeth.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Oct 11th, 2017, 02:37 PM
#35
Re: HOw do I create a variable that will be visible over several forms?
Maybe we are using the wrong metaphor.
-
Oct 11th, 2017, 03:06 PM
#36
Thread Starter
Lively Member
Re: HOw do I create a variable that will be visible over several forms?
Aren't you someone I metaphor?
Mataphors be with you.
What is a metaphor?
Sheep to graze in.
-
Oct 11th, 2017, 03:13 PM
#37
Re: HOw do I create a variable that will be visible over several forms?
"There's no time for metaphors", said the little pill to me.
He said that, "Life is a placebo, masquerading as a simile."
Last edited by Sitten Spynne; Oct 11th, 2017 at 03:21 PM.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Oct 11th, 2017, 03:42 PM
#38
Fanatic Member
Re: HOw do I create a variable that will be visible over several forms?
So let me get this straight. So kpmc, I could actually use this approach just like I do when I set up global variables in a module and it works across all of my form classes, etc.? I like it, but I can see one would lose the ability to have a specific easy to find location and the documentation (comments) explaining what they are and what they are for. Hmmmmm, I am going to have to give this some thought. It is always cool finding new tools. Thanks man.
-
Oct 11th, 2017, 04:36 PM
#39
Re: HOw do I create a variable that will be visible over several forms?
There are some neat things that can be done with Settings, but they really are a different animal than globals. Another point about them is that they don't have the same range of data types that variables in the program have. There are a goodly set, but really just your basic value types (no structures), strings, and a specialized string collection that acts kind of like a List(of String). Meanwhile, a global can be any type, so you can make forms as globals, datasets as globals, and dictionaries(of Dictionary(of String, GUID),Dictionary(of String,Object)) as globals. To get the same thing into a Setting, you'd have to serialize it and put it into a string Setting, then deserialize before use.
I'd say you should use settings when you want to persist state data between runs of the program (which is what it is mostly for), use globals when a global makes sense, and never use sandpaper on your teeth....it's bad for the enamel.
My usual boring signature: Nothing
-
Oct 11th, 2017, 04:57 PM
#40
Re: HOw do I create a variable that will be visible over several forms?
The reason I compared using Settings for this to like brushing your teeth with sandpaper is because:
They are "just like" global variables in that everything in the application can automatically see them and you never have to worry about access control.
They are "worse than" global variables because they are backed by an XML file. That means every get/set has the potential to fail due to weird I/O circumstances. It might not crash your program, but you won't get the value you expect which can lead to a crash. Files on disks can be deleted, corrupted, etc. The I/O can dramatically slow down any loop or other fast code that depends on it.
I can't help myself and have to fire the analogy gun. It's like saying bubble gum "is the same as" duct tape for car body repair. I strongly advise against it and weep for your students if you teach it to them.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|