1

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!

finxie
  • 124
  • 2
  • 13
  • if User is important to both forms make it global. Create a module, add `Friend Usr As User`. then to create an instance: `usr = New User` (no Dim). Now, both forms have access to it. You'd be better off using explicit form instances as well. – Ňɏssa Pøngjǣrdenlarp Jan 21 '15 at 02:16
  • Use a shared model that each form can read. Forms are UI and shouldn't be data repositories. Whatever @Plutonix suggested is also a bad idea. – siride Jan 21 '15 at 02:21
  • possible duplicate of [VB.Net Passing values to another form](http://stackoverflow.com/questions/19618668/vb-net-passing-values-to-another-form) – Nathan Tuggy Jan 21 '15 at 02:27

4 Answers4

1

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

Community
  • 1
  • 1
1

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.

SSS
  • 4,807
  • 1
  • 23
  • 44
  • 1
    You're talking about "default instances" of the Forms. Each instance of frmDisplay would still have its own copy of "usr", though, even the default instance. If you changed `Friend` to `Shared`, however, then all instances of frmDisplay would share the same instance of User making it global. – Idle_Mind Jan 21 '15 at 04:06
  • Yes, this is a VB.NET solution, it won't work with C#. The asker is definitely using default instances though. If you want a more general solution that is C#-friendly, use the custom constructor solution proposed by M J Heier. The asker seems to be a newbie though, and my solution is simpler. – SSS Jan 21 '15 at 04:10
1

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
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
  • Setting `Private usr As User` as `Public Shared usr As User` fixed the problem. Thanks a lot! – finxie Jan 26 '15 at 13:23
0

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.

SSS
  • 4,807
  • 1
  • 23
  • 44
  • Whether to set the `Label1.Text` property in `Sub New()` or `Form_Load` is another debate, lol. I prefer putting it in Form_Load since some controls do some rendering etc. after the ctor which can (for the more complex winform controls) lead to unexpected effects. – SSS Jan 21 '15 at 04:26