Pass variable From child to parent, Like a Function VB.NET - vb.net

I have created 2 forms (Parent & Child), i want to store the unique textbox value to a variable into the parent form.
Also like this:
Parent Code:
dim passed_value = new childform()
passed_value.show()
On close:
refresh passed_value variable using childform textbox value.

You can Do the Following to accomplish the Task :
Declare a String variable in the child form.
Public value As String
Use ShowDialog() in the Main Form to show the Child form.
Dim frm As New Form2
frm.ShowDialog()
[Set the value in your form as per your needs]
value = "New Value"
Now get the value variable from the Child form and set the textbox text according to it.
TextBox1.Text = frm.value

I would make it a property and give it the necessary access, which to me looks to be ReadOnly.
Private _myValue As DataType
Public ReadOnly Property MyValue() As DataType
Get
Return _myValue
End Get
You could access it as such: myForm.MyValue.

Related

ToString not updating on object when altering ListBox in VB

I have a form that alters the content of a class within a list box. The information is updated correctly, but my ToString override on my object doesn't refresh - meaning the old ToString doesn't change. How would I fix this?
Here's my object:
Public Class Destination
Public strDestinationName As String
Public strAddress As String
Public intQuality As Integer
Public intPrice As Integer
Public Overrides Function ToString() As String
Return strDestinationName
End Function
End Class
Here's the code where it should be updated
Dim selectedDestination As Destination
selectedDestination = CType(ListForm.lbNames.SelectedItem, Destination)
selectedDestination.strDestinationName = tbName.Text
selectedDestination.strAddress = tbAddress.Text
selectedDestination.intPrice = cbPrice.SelectedIndex
selectedDestination.intQuality = cbQuality.SelectedIndex
Me.Close()
Regardless of how you add items to a ListBox, it is the ListBox that actually displays the data. In your case, it appears that you are adding Destination objects to the ListBox somehow, given that the SelectedItem is a Destination object. Given that you have written that ToString method, you are presumably relying on that to produce the text that the ListBox displays for each item. You are now expecting to be able to change the value of the strDestinationName field of one of the items and have the ListBox reflect that change. How exactly do you think that is going to happen?
The ToString method has to be called in order to get the new value and who do you think is going to call it? It would be the ListBox that calls it because it is the ListBox that displays the result. When you change that field, you are expecting the ListBox to call your ToString method but why would it do that? What reason has the ListBox got to call that method? It has no knowledge of the change you made so why would it think that it has to get new data?
The solution to your problem is to change your code in some way to notify the ListBox that data has changed so that it knows that it needs to get that new data and display it. There are multiple ways that you could do that.
The simplest option would be to bind your data to the ListBox via a BindingSource and then, when you modify an item, call the ResetItem method or similar of the BindingSource. That will raise an event that is handled by the ListBox and the ListBox then knows that it needs to refresh the data for that item. That is what will prompt the ListBox to call your ToString method and get the new data to display. You would add the BindingSource to the form in the designer and then do the binding where you are currently adding the items, e.g.
Dim destinations As New List(Of Destination)
For i = 1 To 10
Dim d As New Destination
d.strDestinationName = "Destination " & i
destinations.Add(d)
Next
destinationBindingSource.DataSource = destinations
destinationListBox.DataSource = destinationBindingSource
The modification would look something like this:
Dim selectedDestination = DirectCast(destinationBindingSource.Current, Destination)
selectedDestination.strDestinationName = "New Destination"
destinationBindingSource.ResetCurrentItem()
The Current property returns the item currently selected in the bound UI and the ResetCurrentItem method notifies the bound UI to refresh the display of that item.
This is really not the best way to go about it though, given that you have control over the item type. What you ought to do is implement the type using properties rather than fields, get rid of the ToString method that only returns the value of one property and then add a change event to that property:
Public Class Destination
Private _destinationName As String
Public Property DestinationName As String
Get
Return _destinationName
End Get
Set(value As String)
If _destinationName <> value Then
_destinationName = value
OnDestinationNameChanged(EventArgs.Empty)
End If
End Set
End Property
Public Property Address As String
Public Property Quality As Integer
Public Property Price As Integer
Public Event DestinationNameChanged As EventHandler
Protected Overridable Sub OnDestinationNameChanged(e As EventArgs)
RaiseEvent DestinationNameChanged(Me, e)
End Sub
End Class
You can now bind a list of Destination objects directly and specify any of those properties as the DisplayMember to have that property value displayed:
Dim destinations As New List(Of Destination)
For i = 1 To 10
Dim d As New Destination
d.strDestinationName = "Destination " & i
destinations.Add(d)
Next
destinationListBox.DisplayMember = "DestinationName"
destinationListBox.DataSource = destinations
You don't need the ToString method because the DisplayMember specifies that the value of the property with that name should be displayed. When you modify the value of the DestinationName property of an item, it will raise the DestinationNameChanged event and that will notify the ListBox that it needs to refresh the display for that item, so you don't need any additional code to make the ListBox update.
That's fine if you only plan to modify existing items. There's still a problem if you want to add and/or remove items after binding though. The List(Of T) class that is used to bind the items to the control in this example does not have any events to notify the control of changes to the list like that. In that case, you can use a BindingSource again if you want. If you add and remove items via the BindingSource then it will raise that appropriate events and the ListBox will update. If you wanted to add and remove via the underlying list then you'd have to call an appropriate method of the BindingSource when you made a change.
An alternative would be to use a BindingList(Of Destination) instead of a List(Of Destination). As the name suggests, the BindingList(Of T) class is made for binding, so it will automatically raise the appropriate events when the list changes to enable the UI to update without extra code from you. Using the combination of property change events in your item class and a BindingList(Of T), you can add, edit and remove items in the bound list and the UI will reflect those changes automatically.

Looping through dictionary of objects in vba

I'm writing code to instantiate a form that shows one record in each instance. I have functions to open and close instances using a dictionary but now I need to check whether a record is already opened.
Dictionaries and collections only allow you to store pairs of data (key/item) so created a class with two properties: form object and the opened record id. I store key and this object in a dictionary.
Now I want to check if a record id is already opened so I have to loop trough the dictionary checking the record id (servicioid in code below) property of the item.
Class module:
Private propFormulario As Form
Private propServicioId As Long
Public Property Let FormObj(frmFormObj As Form)
Set propFormulario = frmFormObj
End Property
Public Property Get FormObj() As Form
Set FormObj = propFormulario
End Property
Public Property Let servicioid(lngServicioId As Long)
propServicioId = lngServicioId
End Property
Public Property Get servicioid() As Long
servicioid = propServicioId
End Property
Open and close instances:
Public dicFormServicios As New Dictionary
Public Sub AbrirServicio(lngServicioId As Long)
Dim ServicioAbierto As clsServiciosAbiertos
Set ServicioAbierto = New clsServiciosAbiertos
ServicioAbierto.FormObj = New Form_servicios2
ServicioAbierto.servicioid = lngServicioId
dicFormServicios.Add CStr(ServicioAbierto.FormObj.hwnd), ServicioAbierto
ServicioAbierto.FormObj.visible = True
End Sub
Public Sub CerrarServicio(InstanciaHwnd As Long)
If dicFormServicios.Exists(CStr(InstanciaHwnd)) Then
dicFormServicios.Remove CStr(InstanciaHwnd)
End If
End Sub
My question is how do I loop trough the dictionary and how do I check an ID is in the servicioid property of any item.
My VBA is a bit rusty, so you're going to want to do something along the lines of...
dicFormServicios.Add myForm.FormId, myForm
Then to recover a value try...
myReturnForm = dicFormServicios.Item("SomeFormName")
Details here...
Dictionary Object
Whether a value exists
Recover an item from the dictionary
(The Dictionary reference above is very useful, but really...) All of the objects that you need are already there. You can reference an object directly from the Forms collection using either an index number...
Set myForm = Forms![0]
...or by using the form's name...
Set myForm = Forms!["myFormName"]
(Such a long time since I've done any of this stuff!)

How to find parent form name ? vb.net

I want the name of the parent form in vb.net . Where I came from.
Like
`if parent-form.name = 'something' then
do something.
else
do something else.`
It's not a MDI form.
Edit:
I want exactly like that:
parentForm.vb:
chidform.showdialog()
In childform there is textbox
childForm.vb:
if parentForm is parentForm1 than fill textbox.text = 2
else fill textbox.text = 3
You will understand what I want.
Assumption: I worked under the assumption that this is an MDI application and you would want to read the name of the top parent and for reasons unknown you cannot refer to a singleton reference to the form (for instance current form runs from a library).
I wrote an extension mode to get the top parent since the immediate parent of an MDI child window is an MDIClient without a name.
<Extension>
Public Function GetTopParent(currentControl As Control) As Control
Dim parent As Control = Nothing
Do While currentControl IsNot Nothing
parent = If(currentControl.Parent, parent)
currentControl = currentControl.Parent
Loop
Return parent
End Function
Then when you need the name of the parent you can do the following.
MessageBox.Show(Me.GetTopParent().Name) ' This just shows the name but you can do your comparison here.

Passing Array to Another Form (vb.net)

I got a form which declared an array in public,
Public requestedqueue() As Integer
I would like to pass the array to form3 and perform other calculations there, but how?
I tried doing(at a new form):
public newrequest() As Integer
newrequest = form2.requestedqueue
I tried to show it at a new form by doing:
TextBox1.Text = = String.Join(",",form2.newrequest)
But whenever I run into form3 it would say the newrequest is null.
But it shows as an array in form2, Im so confused.
I'm not sure what you mean by
But it shows as an array in form2
but newrequest will be Nothing because you have set it equal to the value of requestedqueue which is Nothing until you populate the array with some values.
If you had Public requestedqueue() As Integer = {1, 2, 3} then you would not encounter the error.
One way to pass data to a form is to add a property to the second form.
Lets say you have a form called Form3 and this is your form's code. In the code you will need to declare an array of integer to hold the passed data, and also declare a public property so you have a way of passing the array
Public Class Form3
Dim requestedqueue() As Integer
Public Property ArrayParameter As Integer()
Get
Return arrayData
End Get
Set(value() As Integer)
arrayData = value
End Set
End Property
End Class
Then, to pass the data from Form1, in form1, you would simply use
Form3.ArrayParameter=requestedqueue()
to set the parameter.
and if you wish, you can show the form as normal, or if the form is already visible, you can process the code using button clicks etc.
If you want to process the data in an already open form immediately without any user interaction, you can write a Procedure that does the processing and include that in the Set portion of your property.
For example. If you want to add all the elements of the array to a ListBox called ListBox1 in Form3, you could write a procedure like this..
Private Sub AddDataToListbox()
ListBox1.Items.Clear()
For Each item As Integer In requestedqueue
ListBox1.Items.Add(item)
Next
End Sub
and change your Form3.ArrayParameter code to this
Public Property ArrayParameter As Integer()
Get
Return requestedqueue
End Get
Set(value() As Integer)
requestedqueue = value
AddDataToListbox()
End Set
End Property

Passing the data between windows forms

I have a windows application.
In which I want to call one form from another and take Yes/No option from user
and that Yes/No choice again passed to the parent form.
How to do this ?
I have tried by creating object but it dont work.
Please check below image...
I have Call conformation form on click of final button, when user choose ok/Cancel that value passed to the again parent form and will take desired action depends on choice.
how to take input from this child form ?
The easiest way is to set a variable to Public when you instantiate it.
Public myVariable as String = ""
Then you would access it from anywhere.
From your own form
Me.myVariable = "" 'Whatever you would like to set
From another Form
Form1.myVariable = "" 'Whatever you would like to set
'or
FormName.Variable = ""
Dim confirmModal = new ConfirmModal
Dim result = confirmModal.ShowDialog()
If result = OK then resltValue = confirmModal.ResultValue
ResultValue is whatever you want to pass to the parent.
You can use a public variable in a module or in the parent form that is accessed by both forms to store the yes/no value.
public returnCode as boolean
If the variable is in the parent form, it can be referenced in the child form using the parent form's name:
form1.returnCode = True