Working with passed data between forms - vb.net

Currently in my windows form, I have a few WinForms to work with. One WinForm acts as a main menu and is supposed to call another form as a secondary window on its own.
Private Sub btnMainGame_Click(sender As Object, e As EventArgs) Handles btnMainGame.Click
' This is the button to call up the main game controller. So simply hide this form aned then open the new form.
Dim frmController As New frmControllerScreen
frmController.Show()
Me.Hide() ' Happens on .Close as well
End Sub
The above code invokes another WinForm which is used to handle more options. When the user clicks on a particular button, a sub form is created again.
Dim OpenNewGameWindow As New frmGameConfig
OpenNewGameWindow.ShowDialog(Me)
Me.DialogResult = DialogResult.None ' Used to prevent the subform from closing the main form when it catches a dialog result.
Now in the frmGameConfig, the program is supposed to take data and pass it back to the form that called it.
Private Sub btnNewGameStartGame_Click(sender As Object, e As EventArgs) Handles btnNewGameStartGame.Click
' ... Skipped code...
frmControllerScreen.MasterQuestionList = QuestionList
frmControllerScreen.blnBankedTime = cbBankedTime.Checked
' ... Skipped code...
End Sub
However, when the frmController tries to reference MasterQuestionList... it returns a nullreference error as if it was not set.
Here's where things get funny...
When I made this code, frmControllerScreen was actually the startup form. Now when I change this form back to frmMainMenu, I get NullReference errors constantly.
My question: How am I supposed to pass information from one form to the next form if it was instantiated from a parent form. (Note I even moved the declartion to Public as a "module-wide" variable... and nothing happens but the same result.) The same error happens even if I go ahead and declare frmController.MasterQuestionList as well.

Instead of trying to pass data back from the called form to the caller, you can reference the called form's controls from the calling code after .ShowDialog.
Dim OpenNewGameWindow As New frmGameConfig
If OpenNewGameWindow.ShowDialog() Then
MasterQuestionList = OpenNewGameWindow.QuestionList
blnBankedTime = OpenNewGameWindow.cbBankedTime.Checked
End If
In OpenGameWindow button click:
Private Sub btnNewGameStartGame_Click(sender As Object, e As EventArgs) Handles btnNewGameStartGame.Click
Me.DialogResult = True
End Sub

Related

vb.net a forms "new" routine is being called before I even invoke the form

I have a form called "partmanager". On it is a button to show another form "parteditor" to allow editing details of a part. Clicking that button will show the form and pass in a variable to the parteditors "new" routine.
My problem is that when the calling form (partmanager) starts, it immediately calls new routine in the parteditor form before it (partmanager) is even initialized so the parteditor form does not get the string that is supposed to be passed in. Later, when the calling form is visible and I click the button to show the parteditor form, new has already been prematurely called and so is not called again and the form does not get the string passed in.
I hope this makes sense!
I can implement a property in the parteditor form and pass in my variable that way prior to showing the form and that will work, thereby not even requiring a "new" routine in the parteditor forms code.
So my question is, is implementing the property the proper way to pass this variable to the form being called, or am I not properly coding my forms? (I also have an intermediary module called "commands" where I have been defining command procedures, in this case just showing a form.)
any pointers would be appreciated, thanks!
here is the code for the button in the calling form:
Private Sub EditButton_Click(sender As Object, e As EventArgs) Handles EditButton.Click
Commands.EditPart(_PartNumber) 'call the editpart command
Me.Close()
Me.Dispose()
End Sub
here is the code for the form being called:
Public Class PartEditForm
Private _partNumber As String = String.Empty
Public Sub New(partNumber As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_partNumber = partNumber
End Sub
Private Sub PartEditForm_Load(sender As Object, e As EventArgs) Handles Me.Load
Label1.Text = _partNumber
End Sub
End Class
and here is the code in my "commands" module for loading/showing the form:
Public PartEditForm As New PartEditForm(_partNumber)
Public Sub EditPart(partnumber As String)
If PartEditForm.IsDisposed Then
PartEditForm = New PartEditForm(partnumber)
End If
PartEditForm.Show()
End Sub
you can save the routine in a dim variable and get this on the other form and close the first form or hide but you need get in new var and contine where stop before.

VB.Net passing datagridview row from one form to another form that is already open

I'm trying to develop a search window that allows a user to fill in criteria, then click the search button. When the search button is clicked the results are returned in a DataGridView. When a result in the DataGridView is clicked, I'd like to pass the row number to another form that is already open.
I understand I can pass the result by creating a new instance of the form. I pass variables to my Search Window using the following method:
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim ST = New Search_Tool(DGV_Ongoing.DataSource, AgencyOptions, EthnicityOptions, EmploymentTypeOptions, EmploymentStatusOptions,
CategoryOptions, OutcomeOptions)
ST.Show()
End Sub
however I cannot call the form I want to pass the row value to because it is already open (its the main form). Is there a way to handle this? I'm struggling to find any information that doesn't call the form to open it whilst passing the data.
I can't reference Main_form.Main_DGV.CurrentCell as Visual Studio says it requires an Object Reference in order to do so.
Thanks in advance!
I'd recommend an event in your Search_Tool form that is raised when the user has found what they're looking for.
The main form is subscribed to that and can then access its datagrid.
Class Search_Tool
Inherits Form
Public Event SearchResultFound(resultId As Integer)
Private Sub OnUserClickedARowOrPressedAButtonOrWhatever()
RaiseEvent SearchResultFound(currentRow.Id)
End Sub
End Class
And in the main form.
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim ST = New Search_Tool(DGV_Ongoing.DataSource, AgencyOptions, EthnicityOptions, EmploymentTypeOptions, EmploymentStatusOptions,
CategoryOptions, OutcomeOptions)
AddHandler ST.SearchResultFound, Sub(result As Integer)
'handle your result id here.
MessageBox.Show("User selected row " & result)
End Sub
ST.Show()
End Sub
The advantage of this is that the SearchForm doesn't need to know what it's being used by. It's just there to give results which will make it easier to reuse later.

How do I use the Tag property with forms and code in VB 2012?

I am writing a program using a database for customers and technicians. The main form (CustomerIncidents) has a toolstripbutton that opens a different form to (SearchByState) where the user inputs a state code and looks for any incidents.
If the user clicks into one of the datagrid cells I want that customers information to be stored in the TAG so that when the form is closed using the OK button that it will show back up in the main form (CustomerIncidents).
Edited 03/11/14 12:21pm
The problem is in the Main Form. When I click the OK button in the Second Form it tries to convert the DialogResult Button to a String. I can't figure out how to fix it.
Customer Form (Main Form) Opens to Secondary Form
Private Sub btnOpenState_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnOpenState.Click
Dim frmSearchState As New FindCustomer
----->>Dim selectedButton As DialogResult = frmSearchState.ShowDialog()
If selectedButton = Windows.Forms.DialogResult.OK Then
CustomerIDToolStripTextBox.Text = frmSearchState.Tag.ToString
End If'
Search By State Form (Secondary Form) Or "Child Form"
Private Sub btnOk_Click(message As String, ByVal e As DataGridViewCellEventArgs) Handles btnOk.Click
message = CustomersDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString
Me.Tag = message
Me.DialogResult = DialogResult.OK
End Sub
The click event for a button does not have a DataGridViewCellEventArgs parameter, and will throw an exception when you try to use it.
You don't need to use the Tag property since you can just create your own property.
In your child form, create a property called GridValue:
Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click
If dgv.CurrentCell Is Nothing OrElse dgv.CurrentCell.Value Is Nothing Then
MessageBox.Show("A cell needs to be selected.")
Else
Me.DialogResult = DialogResult.OK
End If
End Sub
Public ReadOnly Property GridValue As String
Get
Return dgv.CurrentCell.Value.ToString
End Get
End Property
In your parent form, you can now access your information:
Using frmSearchState As New FindCustomer
If frmSearchState.ShowDialog(Me) = DialogResult.Ok Then
CustomerIDToolStripTextBox.Text = frmSearchState.GridValue
End If
End Using
My personal approach for doing this kind of stuff is to create a public property in the child form, having the same type as the DATA you want to take back to your main form. So instead of storing DataGridView's reference in Tag property, you should really be storing the actual value that was there in the cell that the user clicked on.
For example, if your DGV cell has a string value in it, you could do something like:
Public Readonly Property StateName As String
Get
If YourDGV.SelectedCell IsNot Nothing Then
Return YourDGV.SelectedCell.Value
Else
Return ""
End If
End Get
End Property
(I have written that code by hand, so there may be some syntax problems, but you should be able to get the idea.)
You can now use ShowDialog() in the main form to bring up this child form and upon OK or Cancel, you could check the value of StateName property of your child form to get this value. The thing to remember here is that closing a form doesn't dispose off all its constituent controls and properties and therefore you can access them even after the form has finished ShowDialog() call.

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.