Samuel Nicholson
Samuel Nicholson

Reputation: 3629

Storing and keeping values between forms VB.net

Apologies if this is a basic question but I'm still experimenting with VB.net and I'm trying my hand at creating an event log for my test application. (Not Windows event Logs) - I've focused on one event, that being the time my application is launched.

I have two forms and I'm trying to establish a permanent "link" between Form1 and Form2. This means that I can send .NET commands and variables to Form2 and on form close/open the data remains until the main application Form1 is closed.

Take for example the below code I'm running with Form1 is loaded.

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Form2.RichTextBox1.Text = ("Launched @ " & Now.ToShortTimeString())

    End Sub

Form2 is not loaded until a Link Label titled "Event Log" is clicked within Form1. I have a simple Form2 Load command for the click event on my Link Label.

Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked

        Form2.Show()

    End Sub

Form2 consists of one RichText box, the aim of which I will add text on events of my choosing as I build the application.

Now when I debug my application I click my Link Label the test "Launched @ xx" appears in my RichTextBox - However when I close Form2 and then click my LinkLabel the RichTextBox is blank.

Main Questions

MAIN NOTE - I'm planning for the event log to be cleared every time the application is closed, I will write the contents of the RichTextBox to a .txt file on application close.

Thanks for your advice, I would appreciate some documentation or code examples on saving strings/variables and using them between forms.

Upvotes: 0

Views: 2620

Answers (2)

the_lotus
the_lotus

Reputation: 12748

Personally I would not expose the controls of a form. I would create a function inside form2 that sets the text.

Form2.SetText("Launched @ " & Now.ToShortTimeString())

You could create a class to store your logs. This class could be stored in Form1.

Before showing Form2, you could set the log.

Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
    Form2.SetLogs(LogObject)
    Form2.Show()
End Sub

This function would get the content of the log class and output it to the RichTextBox

The log class could look like this.

Public Class Log

    Private _logs As New List(Of String)

    Public Sub Clear()
        _logs.Clear()
    End Sub

    Public Sub AddLog(ByVal message As String)
        _logs.Add(DateTime.Now.ToString() & " " & message)
    End Sub

    Public Function GetLogs() As String
        Return String.Join(vbCrLf, _logs.ToArray())
    End Function

End Class

Upvotes: 2

rory.ap
rory.ap

Reputation: 35270

Where are you holding the instance of Form2? You should maintain a global instance of it, and if you need to "close" it, you should actually just hide it instead. You can accomplish this by handling the Closing event and setting the event arg's "Cancel" to True, this this:

Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    e.Cancel = True
    Me.Hide()
End Sub

That way, the Form2 instance will maintain whatever state it has. By handling the FormClosing event and setting the arg's Cancel property to true, you're telling the app to effectively stop closing the form. That means none of the ways you can actually close a form -- Alt + 4, the red "X", etc. -- will close it, but will instead hide it.

EDIT: I didn't realize that you could actually show a form that you've never instantiated (i.e. that the "Form.Show()" method is a static method). So, when I asked above where you are holding the instance of Form2, what I was driving at is that you should create a global instance of Form2 when Form1 loads, and use that instance throughout. See below:

Private WithEvents frm As Form2 'My global instance.

Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    frm = New Form2
End Sub

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Me.frm.Show()
End Sub

Private Sub frm_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles frm.FormClosing
    e.Cancel = True
    frm.Hide()
End Sub

Note that WithEvents keyword is required so that you can handle the instance's events in the class where the instance is defined.

EDIT: I did some research on why you could use a construction like "Form2.Show()" (i.e. refer to the Show() method without an instance of Form2), and I learned that VB.NET has a "feature" that hearkens back to the early days of VB -- way before .NET (this "feature" is absent, for better or for worse, from C#): there is a default instance of a form created for every form you have in your application, and this is what allows you to call Form2.Show(). The Show() method is not actually a static method (although it appeared that way to me at first), it's referring to the default instance's Show() method.

Here is where I learned all this: Why is there a default instance of every form in VB.Net but not in C#?

Upvotes: 0

Related Questions