ShowDialog() in vb.net not working properly - vb.net

I'm not sure if this question has been already posted or not but since I couldn't find the answer I'm looking for so I'll ask anyways.
When I use ShowDialog() to call another form from the current form it just displays the name of the controls the first time it opens, if I close it and open it again then it displays at it should have. For example if I write a simple code as follows
Form1
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Form2.Display("Message")
End Sub
End Class
Form2
Public Class Form2
Public Sub Display(ByVal msg As String)
Me.ShowDialog(Parent)
Label1.Text = msg
End Sub
End Class
When I click the button the first time all I get is "Label1" instead of "Message" displayed on the called form but when I click on the button a second time I get the desired output.
I tried the same thing with Show() and didn't have any such problem. But I need the called form to be modal (like a MessageBox), so is there any other way to do it or can someone tell me the right way to use ShowDialog() ?
I'm new to vb so please keep it simple.
Thanks

ShowDialog is a blocking call. You need to set everything before you call it.

Related

VB Adding an item to listbox on a different form giving null reference exception

I am getting a an Null reference exception when trying to add an item to a listbox in a different form.
This is my error at run time.
An unhandled exception of type 'System.NullReferenceException'
occurred in ... Additional information: Object reference not set to an
instance of an object.
I am trying to connect the Mainform by initializing it at the top of the class of the secondForm. after I have my data i want to add it to a listbox it the mainform.
Public Class FormHairdresser //The second form
Dim varMainForm As FormMain //connecting the forms ?
Private Sub btnAddHairdresser_Click(sender As Object, e As EventArgs) Handles btnAddHairdresser.Click
hairdresser = HairdresserChoices(HairdresserID) // get the data
varMainForm.lstListBox.Items.Add(hairdresser) //Run time error breaks here.
All i had to to was write the form name instead of ininalised variable.
FormMain.lstListbox.Items.Add("item")
Instead of
Dim varMainForm As FormMain
varMainForm.ListBox.Items.Add("item")
You cannot simply create a new instance of your main form (as has been suggested and expect that to work, you need an actual reference to the mainform that you have created. To help you see the logic involved;
Create a new Winforms project. In the default Form1 add a textbox and a button.
Now add a new form to this application (you can leave it with its default name of Form2. To this form add a TextBox (call it myTextBox) and a button.
Now go back to your first form and doubleclick the button to access the click handler in code. Add the following:
Dim frm as New Form2
frm.Show
Press f5 and click the button and you'll see a new form 2. So far so good.
Now open up the code for Form2 and add the following code so that it ends up looking like this:
Public Class Form2
Private frm As Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
frm.TextBox1.Text = myTextBox.text
End Sub
End Class
build, press f5 and click the button on form1, in the new form2 enter some text in the text box and click the button, you get your null reference exception. The reason you get this is because at the moment the private field frm inForm2 refers to Nothing.
Now open up the code in Form2 and add a constructor and the following code so that it ends up looking like this:
Public Class Form2
Private frm As Form1
Public Sub New(byval frm1 As Form1)
'first we should make sure that we have a parameter to play with
If Not IsNothing(frm1) Then
frm = DirectCast(frm1,Form1)
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
frm.TextBox1.Text = myTextBox.text
End Sub
End Class
Finally go back to your first forms buttonclick handler and change the code slightly so that it looks like this;
Dim frm as New Form2(Me)
frm.Show
Build and run your application, now when you enter text into the textbox in form2 and click the button it will appear in the textbox in Form1.
The reason why this happens is because you have passed an actual reference to the form1 that was originally created when the application started to form2. By casting that reference to your private field used to represent form1 in form2 you can then use it to properly refer to things on form1. This is a very simple concept but one which you need to learn before you will make progress programming.
the Problem is with your initialization of the formmain.with out proper initialization the object you are creating is nothing other than Null.To avoid this we use New Operator.The New operator can often be used to create the instance when you declare it.
So the initialization will look like
Dim varMainForm As New FormMain
Hope this Helps.For more Reference Object Initialization Errors
update:
Dim varMainForm As FormMain //connecting the forms ?
Private Sub btnAddHairdresser_Click(sender As Object, e As EventArgs) Handles btnAddHairdresser.Click
hairdresser = HairdresserChoices(HairdresserID) // get the data
varMainForm = New FormMain
varMainForm.lstListBox.Items.Add(hairdresser) //Run time error breaks here.
Try This.
Public Class FormHairdresser //The second form
Private Sub btnAddHairdresser_Click(sender As Object, e As EventArgs) Handles btnAddHairdresser.Click
Dim varMainForm As FormMain
hairdresser = HairdresserChoices(HairdresserID)
varMainForm.lstListBox.Items.Add(hairdresser)

Create And Implement a Custom Form in VB.NET

I am trying to create a customized form class (CustomBorderlessForm) in VB.NET.
My Progress So Far
I created a new Class and named it CustomBorderlessForm.vb
I then proceeded to write the following code:
CustomBorderlessForm.vb
Public Class CustomBorderlessForm
Inherits Form
Dim _form As Form = Nothing
Public Sub New(form As Form)
_form = form
MsgBox("Testing: New()")
End Sub
Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
MyBase.OnMouseMove(e)
MsgBox("Testing OnMouseMove()")
End Sub
End Class
Form1.vb
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim form As New CustomBorderlessForm(Me)
End Sub
End Class
Results of progress
A message box displays "Testing: New()" on load
Nothing shows on mouse move
As you can see, my problem lies with the events
Questions
Is it possible to create a form object and use that instead of the pre-populating form?
If so, can I give this form custom properties, such as, a border and some boolean values (shadow...etc), just like any other custom object/class?
What am I doing wrong in my current approach?
Why isn't the OnMouseMove being overridden?
Am I initialising the class wrong?
Can it even be done this way?
After creating a form you also need to show it. Change your logic to:
Dim form As New CustomBorderlessForm(Me)
form.Show()
Before you do that, I'd recommend changing from MsgBox to Console.WriteLine(), otherwise you can run into a fun/frustrating little cat and mouse game.
EDIT
Based on the comments, if, from VS you did a "Add New, Windows Form" you can just right-click the project, select property and on the Application tab change the Startup object to your new form. VS only allows you to do this with forms it creates for you (by default, more on this later).
If you wrote that file by hand (which is absolutely fine) you can perform the Show() like I did above and call Me.Hide() to hide the "parent" form. Unfortunately the Load event is fired before the Show event so if you place this in Form1_Load() it won't work. Instead you can use the Shown event like this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim form As New CustomBorderlessForm(Me)
form.Show()
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Me.Hide()
End Sub
Another option has to do with "Application framework". You can read about it here however it basically handles application events that other languages have to manually implement. If you go into your project properties you can uncheck the "Enable application framework" checkbox. This will give you more option in the "Startup object" dropdown. If you add the following code to your project one of the items in the Startup object dropdown menu should now be "Loader"
Public Module Loader
<STAThread()>
Public Sub Main()
Dim form As New CustomBorderlessForm(Nothing)
form.ShowDialog()
End Sub
End Module
You'll notice that the above bypasses Form1 completely. Also, instead of Show() I'm using ShowDialog() because otherwise the form shows and then the program ends.

Open Form as ShowDialog But Close Initation Form

Is there any way to do the following, other than hiding then closing the hidden form later?
Mainform opens SecondForm as show dialog, i need to Open ThirdForm from SecondForm while closing SecondForm while keeping third form acting as "showdialog" on the MainForm?
When you show SecondForm(), pass in MainForm() as the owner to ShowDialog():
Public Class MainForm
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sf As New SecondForm
If sf.ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
' ... do some processing in here ...
End If
End Sub
End Class
Now, in SecondForm(), you can then set the owner of ThirdForm() to that of SecondForm():
Public Class SecondForm
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.Hide()
Dim tf As New ThirdForm
tf.ShowDialog(Me.Owner)
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
End Class
You could simply open the third form from the main form as soon as the second form returns a dialog result
You also might want to look at MDI this gives you more control over what the user can and can't do.
After trying Idle_mind suggestion it was still giving me problems going back and forth between forms continously showing them as .showdialog. I solved my problem just like tinstaafl suggested. I wish i would have got his message before a couple hours of trying different methods before coming up with this one.
When i close each form, i set a boolean flag in the main form. then i call a sub that is in the main form to show the next form as showdialog from the main form. i use the flag which triggers logic in the form im loading whether or not to bind data from datatable so i can edit it.
sorry with all those forms i know it gets confusing. to sum it up, close the dialog form (me.close), set flag so calling code knows what to do once the showdialog code is satisfied.

Display a modeless Form but only one

VB2010. I must be missing something because I couldn't find a solution after searching for an hour. What I want to do is simple. In my app I want to display a modeless form so that it is floating while the user can still interact with the main form.
dim f as New frmColors
f.Show(Me)
But I only want one instance of the form at any time. So how can I prevent more than once instance being displayed, and if there is one instance then just give it focus?
Does something like this work for you, if the form is already visible you can not do a Show, you can just do a BringToFront, also you can check to see if the Form has been disposed so you can New up another one.
Public Class Form1
Dim f As New frmColors
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
If f.IsDisposed Then f = New frmColors 'To handle user closing form
CheckForm(f)
End Sub
Private Sub CheckForm(frm As Form)
If frm.Visible Then
frm.BringToFront()
Else
frm.Show(Me)
End If
End Sub
End Class
Make your form follow the singleton pattern. I can't vouch for this sample, but from the text it appears to do what you want.

Using Variables Across Forms - VB

I've got a fairly simple question (I think) on passing variables between forms using Visual Basic.
I've got a program with 2 forms (Form1 and Form2). Form1 has 3 radio buttons, which the user has to select one of and then loads Form2.
Now I've made it so that if radiobutton1 is picked, the Public Variable "radio_select" will equal "radiobutton1", if radiobutton2 is picked, "radio_select" will equal "radiobutton2".
But whenever I try call "radio_select" in my second form, it comes up blank. Why could this be? And how can I fix it.
I've tried using if form1.radiobutton1.checked = true but I keep getting the first radiobutton, regardless of the radio button I've selected.
I think the form is being unloaded, or there is an issue somewhere there, as it appears none of the variables get passed to the second form, once it has been initialized. Also note, the first form is hidden Me.Hide() when the second form is called.
Have you considered a slight re-design whereby you create a property on Form2 called RadioSelect and then set this from Form1 before showing Form2:
Class Form2
Public Property RadioSelect As String
...
End Class
...
Dim f2 as new Form2()
f2.RadioSelect = "radiobutton2"
f2.Show() ' Or f2.ShowDialog()
This gets you away from an unnecessary public variable and should also ensure Form2 can see what it needs from Form1, or whoever calls it.
Edit:
The following works for me:
Public Class Form1
Public Test As String
Private Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
Test = "I'm Here"
Me.Hide()
Form2.ShowDialog()
End Sub
End Class
Public Class Form2
Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Text = Form1.Test
End Sub
End Class