-
Mar 9th, 2018, 11:45 AM
#1
Thread Starter
Member
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?
-
Mar 9th, 2018, 02:46 PM
#2
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).
-
Mar 9th, 2018, 07:41 PM
#3
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.
-
Mar 10th, 2018, 09:03 PM
#4
Re: Unload Windows page in VB.Net
Originally Posted by jmcilhinney
... 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
-
Mar 10th, 2018, 10:02 PM
#5
Re: Unload Windows page in VB.Net
Originally Posted by passel
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.
-
Mar 10th, 2018, 10:18 PM
#6
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.
-
Mar 11th, 2018, 05:23 AM
#7
Thread Starter
Member
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?
-
Mar 11th, 2018, 06:14 AM
#8
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.
-
Mar 11th, 2018, 06:42 AM
#9
Thread Starter
Member
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.
-
Mar 11th, 2018, 07:01 AM
#10
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.
-
Mar 11th, 2018, 10:10 AM
#11
Thread Starter
Member
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.
-
Mar 11th, 2018, 10:53 PM
#12
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.
-
Mar 12th, 2018, 09:29 AM
#13
Thread Starter
Member
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.
-
Mar 12th, 2018, 09:43 AM
#14
Re: Unload Windows page in VB.Net
Originally Posted by PaMarn
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.
-
Mar 12th, 2018, 12:02 PM
#15
Thread Starter
Member
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
-
Mar 12th, 2018, 12:10 PM
#16
Re: Unload Windows page in VB.Net
Originally Posted by PaMarn
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
-
Mar 12th, 2018, 12:16 PM
#17
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.
-
Mar 12th, 2018, 12:18 PM
#18
Thread Starter
Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|