Use instance or form name when addressing public variables between forms? - vb.net

In vb.net, you can address a public variable from another form using the form name along with the variable.
form2.show
form2.k = 3
However, if you use a form variable to show an instance of the form, you must use that variable name to address the public variable. Two instances of the same form are displayed in the following example. The public variable k is assigned a value of 3 only in the first instance of the form, the one from form2.show. frm.k can be used to assign a value to the other form.
dim frm as new form2
form2.show
frm.show
form2.k = 3
My question: Assuming only one instance of the form is shown in the application, is it reliable to address a public variable using the form name (form2.k), or is it better to show the form with a form variable and use that to refer to the instance of the form (frm.k)? Would the same answer apply to a property as well as a public variable?

Little bit of clarification here. In the case of using the form name to access the variable you are still using an instance to access the variable. It's a feature of VB.Net called the default instance. Essentially VB.Net will maintain a single instance per form type. Under the hood it will translate your code to access this instance variable. This was a very popular feature of VB6 which was ported to VB.Net (in 2005 I believe).
The case where a form is shown once is the exact case this feature was designed for. So yes it's reliable to use it to access the value. This applies to any instance member.
This is of course assuming everything is single threaded.

Definitely #2, use the instance variable. I didn't know that the other syntax still worked! That was a leftover from VB4 that was moved to VB6 for compatibility. I thought they dumped it in .net. Don't think it would even work in C#.

Related

How to use Form Controls in Modules

In my modules, I want to use my controls from my form. For example: I want to set focus on a textbox after a certain Sub.
My current solution is to make a subroutine to set all controls in a public variable (see below).
My questions:
What is the best practice? How do people usually do this?
When should I call my subroutine? (is it the first call in the FORM_LOAD sub?)
Public TBnr As TextBox
Public Sub controlsInitieren()
Set TBnr = Forms("frm_TreeView_Example").pstNr
End Sub
Well, as a general rule, while many platforms seperate out the UI part and the code part? Well, Access is quite much a different approach - it is standard fair to place the required code inside of the form "class" (all forms in Access are a "class", and you can even have muliple instances of the SAME form open more then one time).
So, in general, your code should be in the forms code (class) module.
However, you could and call a external routine.
So in the form, you could call your above routine like this:
Call MySetFocus(me, "NameOfControlToSetFocusTo")
And your sub would look like this:
Sub MySetFocus(f as form, sCtrl as string)
f(sCtrl).SetFocus
End Sub
However, as noted, the amount of code above is more code then simply in the forms code module going:
me.ControlName.SetFocus
However, while the above is a less then ideal example, passing the form "instance" (me) to a external sub or function allows you to referance any property or method or feature that exists in the form in an external routine.
So in place of say
me("LastName") = "Zoo"
In the above sample routine, you would and could go;
f("LastName") = "Zoo"
So any place you would and could use "me" in the form, you can use the form instance you passed from the form. As noted, it is a good idea to use "me", since as I noted, Access does allow multiple copies of the form to be opened at the same time - and thus your code can't distinguish between what form instance you are using unless you pass the current "in context" form. So like in JavaScript, using "this" ?
In access that current instance of the class object is "me", and you are free to pass that instance to any sub or function you want as per above.
The best practice is to use only procedures inside the form code. In such a case you refer to a text box control in this way: Me.Textbox1.SetFocus. If you want to set some controls properties during the form loading, you can do that in the frm_TreeView_Example_Initialize event;
They usually do it in the way I described at item 1;
If you want to use such a strange/unusual way you can do it calling the subroutine whenever you want. But, in order to set a specific property value of the form frm_TreeView_Example controls you can simply use frm_TreeView_Example.TextBox1.SetFocus. You can use this way of setting in a module procedure, even before the form has been shown. You can simply show it in that procedure code using at the end: frm_TreeView_Example.Show;

How to set parent to get access to another form in vb.net?

I got 2 forms:
Input.vb and Writer.vb
When Input was set as default form, I was able to do the following:
In Writer.vb
Input.mymessage = texter.Text
texter is btw an Textbox.
Since I needed to change the default form to another it does not work anymore.
How to fix that? Is there any "set parent" or "Dim Input as Input.Forms.all" way to get it work again?
Already tried Dim Input as new Input.
Edit:
I found the way of using CType(Me.ParentForm, Input).mymessage = texter.Text, but Writer.Parent = Me does not work for me :/
Remember that you have object definitions (classes), object instances of those classes, and variables that have references to those instances.
People tend to forget these things apply to forms, too.
When Input was set as the default form, VB.Net was giving you a default instance for the form, and a special global variable that refers to it with the same name as the class. So the name Input in your code could be one of two different things, depending on the context: the class type, or the special variable for the default instance of that class type.
Now that Input is not the default form, you're not using that default instance any more. When you show the form, you're creating your own instance. The same is true for the Writer form. You have a Writer class, but that's only the definition for an instance of the class you create somewhere. You need to provide this instance of your Writer form with a reference to the instance of the Input form that was created.
You do that the same way you handle object references with any other .Net class.
When going one to another form, instead of using the "Private Sub" I use Public sub, it shares everything in that form to anything else trying to use it.

How to assign an output to a label in a second form through the first form?

I wanna show the output of the calculations in a second form but I am writing the code in the first form. How can I do it?
Use the parent form name in front of the control that you are trying to work with. You may need to set the modifier to Friend.
Say that the label exists in form2 and you have code in form1 that is needing to change it. So you would do it like this: form2.label.text = "the string value here"
However, keep in mind that if the control was created or is owned by a different thread then the one that is trying to edit the control, you will receive a runtime exception.
To resolve that you will need to create a delegate for the calling sub or function.

Is there a way to pass values between forms in vb.net? (Without using a public variable)

I have an application that uses a second form with textBox and button, and i need to pass the text from textBox to the first form. I know how to do it with a public variable, but i would like to know if there is another way to do it without using a public variable.
Yes!
If the forms are part of the same solution, you simply write:
Dim MyVal1 As Integer = Form2.MyVal
MyVal1 exists in whatever form you write it in, and MyVal2 comes from Form2. These variables can only be shared if the forms have the right privacy settings.
If the two forms are part of separate applications, the only way i know of passing variables around is through constructors.
EDIT:
In your case with a textbox, you may be able to apply similar a solution:
Dim val As String = Form2.TextBox1.Text
You can use PUBLIC properties on the second form to read/write info to the other form.
You can overload the NEW method to pass variable during declaration.
You can create a public sub/function on the second form and pass variable byval or byref.
But, I would NEVER use a public variable. That is bad programming.

How to run a string as a command in Visual Basic (VB.NET)

i am running a Sub which takes as arguments a Datatable and a String.
Private Sub Populate(ByVal dttemp As DataTable, ByVal strWhichPart As String)
At one point there is a combobox which is populated with some of the data in the datatable. The name of the combobox is cmd plus the name of the string for example when the string is Person_FirstName the name of the combobox is cmbPerson_FirstName. Then i add items to the combobox like this:
cmbPerson_FirstName.Items.Add(strHold(rr))
My question is this can i make a String into a command? Because i have many comboboxes which have the same name as the string argument of the sub how can i do something like this to work
strWhichPart.Items.Add(strHold(rr))
in which strWhichPart is a string. Is there a command that i can execute a string as a command?
Thank you.
If I understand correctly, just grab the correct control from the Form's Controls collection using the string as the key:
CType(Controls(strWhichPart), ComboBox).Items.Add(strHold(rr))
You can use reflection to achieve this by creating an assembly with the code in a method, but its really not recommended. As in, it's insane. I suspect there are no problems in .NET development that need this approach.
Rather than using this approach, actually pass the relevant combo box as an argument - not an arbitrary string. Combo boxes are objects like anything else. You could create a dictionary which allows you to lookup combo boxes by a string. Something like:
Dictionary(Of String, ComboBox) MyDictionary = new Dictionary(Of String, ComboBox)()
MyDictionary.Add("ComboBoxA", objComboBoxA)
ComboBox objTheComboBox = MyDictionary("ComboBoxA")
The name you give your objects should not be semantically relevant in your code. If I name an object "lstMyObjectNamedThisWayForAReason1" I should NOT be using that to reference it. Instead, there should be a separation between what constitutes a GUI element and how it is referenced.
For example, if I create a WinForms GUI and reference all the items directly, then later have to write another front-end using a different framework I have to rewrite every reference. This isn't a problem if you don't tie your logic directly into your controls.
The only reason to tie them together is laziness and lack of respect for co-workers who might have to improve on your code in future. Why should they care what the GUI looks like? They might not even be using Visual Studio! They certainly can't take your code and use it elsewhere without ripping out your GUI dependency.
With a minor modification of ho1 it worked. Thanks a lot
CType(Controls("cmb" + strWhichPart), ComboBox).Items.Add(strHold(rr))