Passing values of an object between forms in VB.NET - vb.net

Here's my problem.
I'm making a project in VB.NET that (currently) exists out of 1 class (let's call it User.vb here) and 2 WinForms (frmDisplay & frmMain).
Let's say User.vb is currently looking like this:
Public Class User
Private mName As String
Public Sub New(ByVal name As String)
Me.Name = name
End Sub
Public Property Name As String
Get
Return mName
End Get
Set(value As String)
mName = value
End Set
End Property
End Class
Let's also say the form frmDisplay is just a form with a textfield txtString and a button btnSend.
Public Class frmDisplay
Dim usr As New User()
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
usr.Name = txtString.Text
frmMain.Show()
Me.Hide()
End Sub
End Class
On the form frmMain I want to reach the value in the property Name that I stored in the class User on the first form.
The basic idea is (I know it doesn't work):
Public Class frmMain
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lblStoredString.Text = usr.Name << This is where I'm stuck
End Sub
End Class
I googled my problem and read many posts, but I just can't seem to understand it. Maybe you guys can help me. I am new to VB.NET and WinForm-stuff (about 3 months of exp.), but I have done some programming in the past in C# with webapplications.
Every bit of help is greatly appreciated.
Thanks a lot in advance!

Will there only ever be one User.Name that you are interested in throughout the app?
If yes, then change the class to:
Public Class User
Public Shared Name As String
End Class
Then you can use User.Name from any form (or anywhere in the application) to get/set that value.
Note that you can still wrap the field in a property if you like:
Public Class User
Private Shared _Name As String
Public Shared Property Name As String
Get
Return _Name
End Get
Set(value As String)
If (value.Trim <> "") Then
_Name = value.Trim
End If
End Set
End Property
End Class

My focus is ASP.NET, and I prefer C#, but I'll chime in. There are numerous ways of providing data between the forms. The first one that comes to mind is to use a cache of some kind. The idea is that once the cache is made available to your program, you can add the value to the cache when the button is clicked, and then safely read the value whenever you need it. This can be a static class with a Dictionary, or you can look into using the functionality provided by the System.Web.Caching namespace. http://www.codeproject.com/Articles/8977/Using-Cache-in-Your-WinForms-Applications has an example.
Another way would be to use a shared data source. The concept is similar to the caching, but this would allow you to pass more complex relational data between your forms, assuming your real goal is more complicated than you describe. Here is a walkthrough for that: https://msdn.microsoft.com/en-us/library/ms171925.aspx.
You could be quick and dirty, and write the values to a text file at some location, and then read the values from the second form.
The simplest way is probably to define a custom constructor for the second form, and pass the values you need when you instantiate the second form. This is best suited if the values from the first form can be considered "parameters" to the instance of the second form. Passing a textbox value from one form to another in windows application

Declare the usr variable Friend
Public Class frmDisplay
Friend usr As New User()
It will then be available from the other form
Public Class frmMain
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lblStoredString.Text = frmDisplay.usr.Name
End Sub
End Class
It's a quirk of VB.NET that forms are automatically created with a public variable name the same as the class name. That's why you are able to use frmMain without having to create it (e.g. Dim frmMain as New frmMain). You can turn off this behaviour, but it isn't relevant to your problem.

On the other hand, if you want to do it "properly"...
Public Class frmDisplay
Private usr As User
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
usr = New User(txtString.Text)
Dim f As New frmMain(Me, usr)
f.Show()
Me.Hide()
End Sub
End Class
and frmMain...
Public Class frmMain
Private myParent As Form
Private usr As User
Sub New(parent As Form, _usr As User)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
usr = _usr
myParent = parent
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = usr.Name
End Sub
Private Sub frmMain_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
myParent.Show()
End Sub
End Class
Here we instantiate frmMain and pass the User object to its constructor. We also pass the calling form so we can display it again when frmMain is closed.

Related

How to check which form is used to access current form?

I have 3 forms, namely Form1, Form2 & Form3.
Both Form1 and Form2 are able to access to Form3. However, I am going to give different function to a button in Form3 depends which form is used to access Form3.
Is anyone free to explain it to me how to code should work? Also, if you guys have link that this question previously answered or better concept, I will highly appreciate it. Thanks in advance.
My rough idea:
Public Class Form3
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If 'user are access from Form1 Then
'Action if user are access from Form1 here
Else
'Action if user are access from Form2 here
End If
End Sub
End Class
The problem with this code
If Me.Owner.Equals(Form1) Then . . .
this way you have tightly coupled objects - Form2 and 1 knows Form3 and Form3 knows 2 and 1. It may be not a problem for you or for now. But in OOP it is a problem, and in the future it may be a problem for your object scalability. Here is OOP approach. Writing from my head, so there could be syntactically incorrect items:
Public Interface IFormCanDoSomething
Sub DoSomething()
ReadOnly Property FormAction As EnumFormActions
End Interface
Public Class Form1
Implements IFormCanDoSomething
ReadOnly Property FormAction As EnumFormActions Implements IFormCanDoSomething.FormAction
Get
Return EnumFormActions.Action1
End Get
End Property
Sub DoSomething() Implements IFormCanDoSomething.DoSomething
Dim f As New Form3(Me)
f.Show()
End Sub
End Class
Public Class Form2
Implements IFormCanDoSomething
ReadOnly Property FormAction As EnumFormActions Implements IFormCanDoSomething.FormAction
Get
Return EnumFormActions.Action2
End Get
End Property
Sub DoSomething() Implements IFormCanDoSomething.DoSomething
Dim f As New Form3(Me)
f.Show()
End Sub
End Class
Public Class Form3
Private _owner As IFormCanDoSomething
Public Sub New(owner As IFormCanDoSomething)
_owner = owner
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If _owner.FormAction = EnumFormActions.Action1 Then
'Action if user needs one thing
ElseIf _owner.FormAction = EnumFormActions.Action2 Then
'Action if user needs another thing here
ElseIf _owner.FormAction = EnumFormActions.Action3 Then
'Action if user needs third thing
End If
End Sub
End Class
So what is the gain here? Look at Button1_Click. Do you see? - now you can have many forms for which Form3 needs to perform Action1, or/and many forms that Form3 needs to perform Action2, etc. This could go farther but for now good enough
Assuming you're using the Show method, pass the Form as the Owner into it:
Form3.Show(Form1)
Then reference the Form3 Owner:
Public Class Form3
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Me.Owner.Equals(Form1) Then
'Action if user are access from Form1 here
ElseIf Me.Owner.Equals(Form2) Then
'Action if user are access from Form2 here
End If
End Sub
End Class

Form data erased after Windows form is closed

I have a subsidiary form where I can enter data and then save it before closing the form and going back to using the main form.
When I re-open the subsidiary form, I cannot see the changes in the data that I had entered earlier.
Can anyone tell me where I'm wrong ?
MainForm.vb
Public Class Maincls
oTestObj as New Testcls
oTestObj.XYZ = "XYZ"
Private Sub SoftwareSettingsToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SoftwareSettingsToolStripMenuItem.Click
Testcls.tbXYZ.Text = oTestObj.m_XYZ
Testcls.Show()
End Sub
End Class
Form_Testcls.vb
Public Class Testcls
Structure Params
Dim m_XYZ as String
End Structure
Dim oParams as Params
Public Sub New ()
InitializeComponent()
End Sub
Private Sub btnOK_Click(sender As System.Object, e As System.EventArgs) Handles btnOK.Click
XYZ = tbXYZ.Text
Me.Hide()
End Sub
Public Property XYZ() As String
Get
Return Me.oparams.m_XYZ
End Get
Set(ByVal value As String)
Me.oparams.m_XYZ = value
End Set
End Property
End Class
I think in windows forms the work around for this is to create a static class and add properties according to your requirement. Then populate these static properties on closing of your form. Now you can use the value set in the static data members, unless otherwise you change them on any other event.
Edit: In vb.net the Static is actually NonInheritable

Way to pass data between forms (VB 2008)

Is this way a "right" way to pass data between two forms?
'Form1 code
Public Class Form1
Public str As New String = "This is the string"
'...more code
End Class
'Form2 code
Public Class Form2
Public str2 As New string = ""
Private Sub Form2_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
str2 = Form1.str
End Sub
'...more code
End Class
Thank you in advance,
Tassos
You want to reference a specific instance of Form1, rather than use it's type name. I know VB.Net provides default instances for forms with the same name as the type name, but this is mainly for compatibility and feature parity with old vb6 code, and there are some good reasons not to use the default instances with .Net.
Additionally, most of the time you have a public field, you should use a property instead.
In form1 code..
put this in button code or something that you will use...
Form2.str2.Tostring = str.Tostring()
I hopes i give you idea....

VB.NET get type of derived generic list class from list item method

Public Class notifierMain
Public Class Contacts
Inherits List(Of row)
Public Sub New()
Dim r As New row()
Me.Add(r)
End Sub
Public Class row
Public Sub Validate()
Dim curType As String = Me.GetType().ToString
End Sub
End Class
End Class
Public Class MyContacts
Inherits contacts
End Class
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim c As MyContacts = New MyContacts()
c(0).Validate()
End Sub
End Class
When I debug this winforms application I get curType = "notifier.notifierMain+Contacts+row"
I want to the Validate function to know it is in MyContacts. How do I do this?
You're tostring()'ing gettype which returns a property called full name.
just check the .Name after get type and that'll have the result you want.
btw: this is a weird example, if you want validate() to return the name of the class you'll have to declare it as a function.
:)
The Me.GetType() is always going to return the type of the class it is enclosed in.
You will need to change Validate to a function and pass in the type of object being validated, but then you might as well call c(0).GetType() outside if the validation anyway!
See MSDN documentation for GetType
You can explore your generic type as shown in this MSDN article:
http://msdn.microsoft.com/en-us/library/b8ytshk6.aspx
Hope this helps.

multiple forms in vb.net

can we have a single global variable which can be manipulated by multiple forms
In short, yes. You can have a global variable in a module (.mod) file or a class (.vb) file.
Module Module2
Public variable As String = "Testing"
End Module
Declare a variable like this:
Public Shared myVariable as Type
and access it from any form.
You can access a single variable from any form, if it is declared as public.
If you are defining it in form1 and want to use it in form2, then from inside form2 you can call the variable as - form1.<variable_name>
Take an example-
Form1 code
Public Class Form1
Public a As Integer = 10
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Form2.Show()
End Sub
End Class
Form 2 code
Public Class Form2
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
MsgBox(Form1.a)
End Sub
End Class
Yes, it can be done. If you declare it as shared it will exist in only one instance.
Public Class SomeClass
Public Shared SomeField As String
End Class
I would, however, recommend to wrap access to the field into a property:
Public Class SomeClass
Private Shared _someValue As String
Public Shared Property SomeProperty() As String
Get
Return _someValue
End Get
Set(ByVal value As String)
_someValue = value
End Set
End Property
End Class
By wrapping it into a property you will make it easier to troubleshoot problems around the value in case such scenarios would appear in the future.
What you are looking for is the "singleton pattern".
But first, you should ask yourself if you really need it. Maybe this variable could be passe as a parameter to a function or a property.
Use
Public x As Integer
On any Of the Forms and then when you want to use that variable on other form then you can type the form name and then a dot and then the variable name
like this
form1.x
Cheers!!!