Results 1 to 18 of 18

Thread: Unload Windows page in VB.Net

  1. #1

    Thread Starter
    Member
    Join Date
    Jan 2015
    Posts
    40

    Unload Windows page in VB.Net

    I want to unload a page so that the next time it's shown it goes through the Load process again. There was a simple command for this in VB3 (unload Form1) but I can't find one for VB.Net. It must be possible, surely?

  2. #2
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Unload Windows page in VB.Net

    You could try Form1.Close.
    VB.Net added creating Default Instances of a form to emulate what VB6 does when you call the Show method, but be aware that depending on where the code is you're trying to access the form from, you could be referencing a different instance of the form that is created in that context.

    I don't have a good example of where using the default instance can trip you up, but it may only be an issue when different threads are involved. Give the Close method a shot and see if it works for you.

    Also a search on VB.Net default instance to see what issues there may be.

    If you are simply showing other forms (using .Show) from your main form and then closing them from the main form (Form2.Close), the default instance should work as it did in VB6 (which is why they added that capability to .Net, although it is controversial).

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Unload Windows page in VB.Net

    Maybe you could show us what you're doing now so that we can determine exactly what needs to be changed. If you are calling Show on the form then that instance is already being disposed when it's closed so a new instance will have to be created next time, even if you are using the default instance. If you are calling ShowDialog then you should be creating an instance with a Using statement, in which case it will be disposed at the End Using statement and you will inherently be creating a new instance next time around. We shouldn't have to guess at this stuff though. You should be providing a FULL and CLEAR explanation of the problem, which ALWAYS includes what you're doing now.

  4. #4
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Unload Windows page in VB.Net

    Quote Originally Posted by jmcilhinney View Post
    ... If you are calling Show on the form then that instance is already being disposed when it's closed so a new instance will have to be created next time, even if you are using the default instance. ...
    I thought that would be case myself, but when I tested it, i.e. had two buttons on the main form (Form1), one button that did a Form2.Show and the second button did a Form2.Close, I didn't have to explicitly create a new instance.

    I had the Load event handler on Form2 set a variable to a number and display it in a label on form2.
    I had a button on Form2 that would change the variable value and update the label on form2.

    Each time I closed Form2 with the second button on Form1, and then hit the first button on Form1 to do a Form2.Show, it worked fine, showing Form2 and the label displayed the original value that was set in the Form load event handler.
    This pretty much mimics the way VB6 worked, where calling the show method will load a new instance of the form if it didn't already exist, otherwise it will just show the existing form.

    With vb.net if the form didn't exist when show was called, it was created, shown and given the focus, although the GotFocus handler isn't triggered.
    In VB6 it would do the same thing, but the GotFocus event for the shown form would be triggered.

    If the form is already showing, the difference in behavior is greater.
    In the case of VB6, the form that Show was called on was brought to the front and got the focus, triggering the GotFocus event.
    With VB.Net, nothing obvious happens. The form is already showing, it is not brought to the foreground or given the Focus. Focus stays on the main form, with the button clicked on.

    With the .Net version of VB I had a second button on Form2 just to check if Form2 would be able to reference a public variable on Form1 each time Form2 was shown without having to pass it an explicit reference to Form1. That worked fine also in this simple test. I didn't bother testing in VB6 since it doesn't have the same "default instance" issue that the .Net version can have.

    VB Net test code Form 1
    Code:
    Public Class Form1
      Public cnt As Integer
    
      Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      End Sub
    
      Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        cnt += 1
        Form2.Show()
      End Sub
    
      Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        Form2.Close()
      End Sub
    End Class
    VB Net test code Form 2
    Code:
    Public Class Form2
    
      Private a As Integer = 5
    
      Private Sub Form2_GotFocus(sender As Object, e As System.EventArgs) Handles Me.GotFocus
        Debug.Print("Got Focus {0}", a)
      End Sub
    
      Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Label1.Text = a.ToString
      End Sub
    
      Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        a = 3
        Label1.Text = a.ToString
      End Sub
    
      Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        Label1.Text = Form1.cnt.ToString
      End Sub
    
    End Class
    VB6 test code Form1
    Code:
    Option Explicit
    
    Private Sub Command1_Click()
      Form2.Show
    End Sub
    
    Private Sub Command2_Click()
      Unload Form2
    End Sub
    VB6 test code Form2
    Code:
    Option Explicit
    Private a As Integer
    
    Private Sub Form_Load()
      a = 5
      Label1.Caption = a
    End Sub
    
    Private Sub Command1_Click()
      a = 3
      Label1.Caption = a
    End Sub
    
    Private Sub Command1_GotFocus()
      Debug.Print "Got Focus", a
    End Sub

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Unload Windows page in VB.Net

    Quote Originally Posted by passel View Post
    I thought that would be case myself, but when I tested it, i.e. had two buttons on the main form (Form1), one button that did a Form2.Show and the second button did a Form2.Close, I didn't have to explicitly create a new instance.
    I didn't say that you would have to create a new instance explicitly; just that a new instance would have to be created. The default instance mechanism built into VB will create the new instance automatically. Accessing the default instance via the class name is simply syntactic sugar. Under the hood, there's a variable that can refer to an instance of the class. Just as you would do yourself, the system tests that variable to see if it is Nothing or the object it refers to is disposed and, if it is, creates a new instance and assigns it to the variable.

  6. #6
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Unload Windows page in VB.Net

    Ok. I guess I thought you were saying something different, but you were just agreeing with me that calling the .Close method of the form is analogous to the Unload statement of VB6, which gets rid of the form so that it will be created anew when you call the Show method, thus going "through the Load process again" as the OP asked.

    He was familiar with the Unload statement from VB6, but didn't now what the corresponding method in .Net was, and I think we agree that the .Close method is what he was looking for.

  7. #7

    Thread Starter
    Member
    Join Date
    Jan 2015
    Posts
    40

    Re: Unload Windows page in VB.Net

    OK, to explain what I'm doing:

    Form1 gives the user various options including text size for the whole project. When Form2 is first shown, Form2_load creates a number of labels in the chosen text size. But if the user returns to Form1 and selects a different text size, then again goes to Form2, the text size has not changed, because Form2_Load has not been not executed. OK, this can be overcome with Me.Close() in Form2 instead of Me.Hide(). (You're right passel, I wasn't aware that VB6 'Unload' is 'Close' in .Net. Is there a language dictionary anywhere that gives such equivalents?)

    However I would have liked the user to be able to end the application from Form2 with the X in the control box, i.e. by closing Form2. Can it only be one or the other?

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Unload Windows page in VB.Net

    I asked you in post #3 to show us what you're doing and you have not done that. If you ask for help and someone asks you for more information in order to do that, it's a good idea to provide that information. There will be a way to do what you want but exactly what it is depends on the specifics of how your forms are related. If we don't have to guess about the details then we can more likely get the solution right first time.

  9. #9

    Thread Starter
    Member
    Join Date
    Jan 2015
    Posts
    40

    Re: Unload Windows page in VB.Net

    I'm not sure just what else you need to know but here's the whole story.

    Form1 displays a number of English grammar topics. When the user selects one of these, Form1 hides and Form2 is displayed. Here there are a number of sentences displayed in labels which Form2_load has created in a particular text size. Having read and listened to the sentences, the user can return to Form1 and choose another topic.

    Form1 also gives the user the opportunity to change the text size, but as this has already been set in Form2_load, it doesn't change when Form2 is shown again.

    To let the user end the program from the Form2 control box I have this:

    Private Sub Form2_Closed(sender As Object, e As EventArgs) Handles Me.Closed
    End
    End Sub

    But if Form2 closes to return to Form1, the program will end.

  10. #10
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Unload Windows page in VB.Net

    I think jmcihinney is correct.
    Most likely you're bring a bad VB6 design to .Net when you should be taking this opportunity to do things better.
    There was probably little reason to unload a form in VB6 and reload it.
    If there was code in the Load event that set the size of the labels and other initialization, that should have been put into a subroutine and called from the load event. Later, if you needed to rerun the code you could call that sub again, rather than force it to be triggered by a fresh reload of the form.

    Once you have that fixed so you don't close the form arbitrarily, you can add something that will allow closing the application from multiple places if that is what you want to do.

    I'll be busy today at work, so probably won't be responding, but if you show the code you're currently running in your load events, then perhaps jmc or others can suggest a better approach rather than try to kludge something together based on closing the form and having to detect how the form was closed and working around the normal way that windows is designed to work.

  11. #11

    Thread Starter
    Member
    Join Date
    Jan 2015
    Posts
    40

    Re: Unload Windows page in VB.Net

    You're right. I'm still thinking in terms of VB6. I bought a book on VB.Net but after a few chapters I decided a better way to learn would be to try to create something and learn by doing. Lacking any inspiration for a new application, I have been trying to recreate one that I made some time ago in VB6.

    Creating the labels in a sub-routine seems the sensible solution to my problem, so I added this, which is called from a Timer when Form2 is shown:

    Private Sub CreateLabels()
    Dim i As Integer
    For i = 0 To 19
    Dim label As New Label()
    label.Location = New Point(0, TextSize * i * 2)
    label.Size = New Size(100, TextSize * 2)
    label.Font = New System.Drawing.Font("Microsoft Sans Serif", TextSize, System.Drawing.GraphicsUnit.Point)
    label.Name = "Panel3.Controls(LabelName)" & i + 1
    AddHandler label.Click, AddressOf SelectLabel
    Panel3.Controls.Add(label)
    Next
    End Sub

    It works the first time with whatever text size I choose, but trying it again with a different text size doesn't (the font size stays the same). Thinking it through, as Form2 wasn't closed, the first set of labels will still be there. Is there a way I can remove them before creating a new set? It would have to check first to see if there were any labels already there.

  12. #12
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Unload Windows page in VB.Net

    I just did a quick test, and was able to change the textsize, and the resulting size of the labels fine.
    I added setting the borderstyle initially so I could see where the labels were placed and their size.
    I then added later setting the text of the label so I could see the font size changed.

    There was no reason to remove the labels and add them again just to change the size and position or font.
    I just created the labels and added a reference to them to an array for convenient access and added the reference to the panel's controls for display purposes.
    Then when I want to access the labels to change them in someway, I just access them through the array of labels rather than deal with the panels collection of controls.

    So, the labels were created and added to the array and panel once at the beginning.
    Then the labels were sized and positioned in a separate sub, so that they could be sized and positioned again later whenever needed. No need to recreate them.
    I just added a button to do the single test, going from the size of 8 to the size of 10 with the press of the button.
    Code:
    Public Class Form1
    
      Dim LabelArray(19) As Label
    
      Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        CreateLabels()
        PositionAndSizeLabels(8)
      End Sub
    
      Private Sub CreateLabels()
        For i As Integer = 0 To 19
          Dim label As New Label()
          label.Name = "Panel3.Controls(LabelName)" & i + 1
          AddHandler label.Click, AddressOf SelectLabel
          LabelArray(i) = label
          Panel3.Controls.Add(label)
          label.BorderStyle = BorderStyle.FixedSingle
          label.AutoSize = False
          label.Text = label.Name
        Next
      End Sub
    
      Private Sub PositionAndSizeLabels(TextSize As Integer)
        Dim fnt As New System.Drawing.Font("Microsoft Sans Serif", TextSize, System.Drawing.GraphicsUnit.Point)
        For i As Integer = 0 To 19
          With LabelArray(i)
            .Location = New Point(0, TextSize * i * 2)
            .Size = New Size(100, TextSize * 2)
            .Font = fnt
          End With
        Next
      End Sub
    
      Private Sub SelectLabel(sender As System.Object, e As System.EventArgs)
        Dim lbl As Label = DirectCast(sender, Label)
        Me.Text = String.Format("{0} Clicked", lbl.Name)
      End Sub
    
      Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        PositionAndSizeLabels(10)
      End Sub
    End Class
    p.s. those are odd names for a label.
    Last edited by passel; Mar 11th, 2018 at 10:58 PM.

  13. #13

    Thread Starter
    Member
    Join Date
    Jan 2015
    Posts
    40

    Re: Unload Windows page in VB.Net

    I was misled by the fact that at runtime you can't change the font of a label created at design time. I assumed the same would apply to labels created at runtime. Your code above solves everything. Many many thanks.

  14. #14
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Unload Windows page in VB.Net

    Quote Originally Posted by PaMarn View Post
    I was misled by the fact that at runtime you can't change the font of a label created at design time. I assumed the same would apply to labels created at runtime. Your code above solves everything. Many many thanks.
    Why do you believe you can't change a Label's font at runtime? This is not true. What did you try, and how did it fail? You'll probably learn more from examining that failure than seeing "how to do it" alone.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  15. #15

    Thread Starter
    Member
    Join Date
    Jan 2015
    Posts
    40

    Re: Unload Windows page in VB.Net

    Label1.Font.Name = "Verdana" gets message: Property 'Name' is 'Read only
    Label1.Font.Size = 12 gets message: Property 'Size' is 'Read only

  16. #16
    PowerPoster
    Join Date
    Nov 2017
    Posts
    3,116

    Re: Unload Windows page in VB.Net

    Quote Originally Posted by PaMarn View Post
    Label1.Font.Name = "Verdana" gets message: Property 'Name' is 'Read only
    Label1.Font.Size = 12 gets message: Property 'Size' is 'Read only
    Yep. So, when you encounter that, the key is to not assume that it then can't be done. All kinds of info on a Google search of relevant keywords like vb.net change font label

    https://stackoverflow.com/questions/...-size-changing

  17. #17
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Unload Windows page in VB.Net

    That isn't how you change a font, and this bit is a little confusing.

    If you take a peek at the Font class's documentation, you'll find that every property is read-only. That is, you can get the values, but you can't change them. This means the Font class is what we call "immutable", which means "can't change". This seems stupid, and it is inconvenient, but there's a good reason. The Font class represents Font objects in GDI, and they are immutable too. Even if you want to do something trivial like change the Font size, you have to create a new Font object in GDI. Why do something that stupid?

    Well, 15 different controls on your Form might be sharing that Font. So if you make a change to it, all of them might have to update. That's probably not what you intend when you try to change a Label's font size. So MS makes you create a new Font object to change it so it's REALLY clear when you do want the changes to be shared.

    That's why there are so many constructors (Sub New) on the Font object. MS knows you usually want to change just one property, so they made constructors that make it sort of easy to get a new Font with the changed property. For example, if you want to increase a label's font size:
    Code:
    Dim oldFont As Font = Label1.Font
    Dim newFont As New Font(oldFont.FontFamily, oldFont.SizeInPoints + 4)
    Label1.Font = newFont
    So in short: you can't change properties of a Font, so you make a new Font with different properties when you want to change one.

    In the future: if you think something that should be easy is hard, ask a question about it here! Often, there's a way to do it. If there's not, then we'll all complain about how stupid it is along with you and offer our workarounds. Either way, you learn something!
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  18. #18

    Thread Starter
    Member
    Join Date
    Jan 2015
    Posts
    40

    Re: Unload Windows page in VB.Net

    OK. It's solved now anyway, thanks to you.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width