How do I pass a value from one TextBox to another TextBox in a different form? - vb.net

Currently I have a TextBox on the first form called txtuserid and I want to pass the value of this to another TextBox called USERIDTextBox on a second form.
But when I try to run my code below, nothing gets passed to the TextBox on the second form. So I'm just wondering how I can pass this value from one form to another form?
Here is my code:
Private Sub cmdlogin_Click(sender As Object, e As EventArgs) Handles cmdlogin.Click
Try
If cn.State = ConnectionState.Open Then
cn.Close()
End If
cn.Open()
cmd.CommandText = "select userid,state from registration where userid= " & _
"'" & txtuserid.Text & "' and state='" & txtpw.Text & "'"
Dim dr As OleDb.OleDbDataReader
dr = cmd.ExecuteReader
If (dr.HasRows) Then
While dr.Read
' My Problem:
' This code shows the 2nd form but the USERIDTextBox value doesn't change?
Dim obj As New Sale
obj.USERIDTextBox.Text = txtuserid.Text
obj.Show()
End While
Else
MsgBox("Invalid username or PW")
End If
cn.Close()
Catch ex As Exception
End Try
End Sub

As a general rule, it's not a good idea to try accessing another object/forms controls directly. Instead, a better way to do it would be to pass the text in the 1st form's TextBox to a custom constructor on the 2nd form (the Sale one). Then the constructor on the 2nd form will be responsible for setting the value of the TextBox .
Here is an example of one way you could do this:
Sale.vb
Public Class Sale
Dim secondFormInputText As String
Public Sub New(inputTextFromFirstForm As String)
InitializeComponent()
' Set the class variable to whatever text string was passed to this form
secondFormInputText = inputTextFromFirstForm
End Sub
Private Sub Sale_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Set the textbox text using this class variable
USERIDTextBox.Text = secondFormInputText
End Sub
End Class
Login.vb
Private Sub cmdLoginExample_Click(sender As Object, e As EventArgs) Handles cmdLogin.Click
Dim obj As New Sale(txtuserid.Text)
obj.Show()
End Sub
So now instead of setting the Sale form's TextBox directly, you can pass the text on the 1st form to the constructor of the 2nd form. The constructor can then save the text it received to a class variable that the rest of the 2nd form can use.
One of the main benefits of this, is that if in the future you change your TextBox to a RichTextBox or possibly another control that might not even have a Text property, you won't have to go updating every single piece of code that tries to set the textbox value directly.
Instead you can change the TextBox to some other control, update the Sales form once with whatever changes you need to work with the new control, and none of the code on the other forms should need to be changed.
Edit:
Even though this question was specifically about how to pass a textbox value from one form to another form, you may also like to read the comments under your question. In particular, Plutonix had some very helpful advice on how you can improve your database code which might be of use to you.

Related

Search in form1 and display it to the form2 using vb.net windows form

In my form1 I have textbox where the user input their employee_number, and i have a second form where the data of that client will displayed.
This is my first form
Dim dt As New DataTable
Dim EmployeeNumber = EmployeeNumber_TextBox1.Text.Trim()
Try
Using MyCon As New Odbc.OdbcConnection("Driver={PostgreSQL ANSI};database=contacttracing;server=localhost;port=5432;uid=ctadmin;sslmode=disable;readonly=0;protocol=7.4;User ID=*****;password=*****;"),
cmd As New Odbc.OdbcCommand("SELECT firstname FROM ""TracingApp_fmcustomeremployeesupplier"" where employee_number='" & EmployeeNumber & "' ", MyCon)
MyCon.Open()
dt.Load(cmd.ExecuteReader)
EmployeeInformation.Show()
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
how do I do that when the employee enters their number in form1 the data will be displayed in the form2 textbox?
form1
form2
i dont have code yet in my form2 cause i dont know how to get the data from form1 and displayed it to form2
Always use Parameters. User input can be malicious. Parameters indicate to the database that this is only a value not executable code. Parameters help to prevent sql injection.
I changed the names of your controls to match my test program. Of course in your code you would use descriptive names.
In you CommandText, select all the fields you need to display. I had to guess at the names of the fields. Check your database for the correct names. Use the name of the parameter in the Where clause.
When you .Add the parameter check your database for the correct datatype. Since your code had the value of the parameter in single quotes I guessed VarChar. If it is an Int or some other number type be sure to CInt(TextBox1.Text) or whatever datatype you need to change to. You have probably validated the input elsewhere.
Only after the connection and command are disposed do we start using the data returned.
vb.net can work with what is called "the default instance" of forms. That is why this code worked. You can also create you own instance.
dt(0)(0).ToString
This refers to the first row, first column in the DataTable. (Arrays and Collections in .net are zero based)
dt(0)(1).ToString
Refers to the first row, second column or the DataTable and so on.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt As New DataTable
Dim EmployeeNumber = TextBox1.Text.Trim()
Try
Using MyCon As New Odbc.OdbcConnection("Driver={PostgreSQL ANSI};database=contacttracing;server=localhost;port=5432;uid=ctadmin;sslmode=disable;readonly=0;protocol=7.4;User ID=*****;password=*****;"),
cmd As New Odbc.OdbcCommand("SELECT firstname, middlename, lastname FROM ""TracingApp_fmcustomeremployeesupplier"" where employee_number= #empNum' ", MyCon)
cmd.Parameters.Add("#empNum", OdbcType.VarChar).Value = EmployeeNumber
MyCon.Open()
dt.Load(cmd.ExecuteReader)
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Form2.TextBox1.Text = dt(0)(0).ToString
Form2.TextBox2.Text = dt(0)(1).ToString
Form2.TextBox3.Text = dt(0)(2).ToString
Form2.Show()
End Sub
You have at least two more options:
Send an event from Form1 to Form2, which is a safer method. If the user has closed Form2, then Form1 will trigger an exception, unless you check that the form Form2 is indeed loaded and accessible. I think it is more elegant to broadcast an event and let the target form react to it.
Overload the Show (or ShowDialog) method of the target form
You could overload the Show method in Form2 like this:
Public Class Form2
Inherits System.Windows.Forms.Form
Public Overloads Sub Show(ByVal ContactD As Integer)
' load the contact from DB
MyBase.Show()
End Sub
End Class
Basically, you add an alternative declaration for the method. Then in Form1 you instantiate Form2 like this:
Dim frm2 as new Form2
frm2.Show(123456) ' ContactID value
And you let Form2 fetch the data from the DB. So I think sending a contact ID or some primary key is sufficient, but you can send more variables if you want. In this case you could send a DataRow.

How to pass a form, object or data to a second form

I have created 2 forms.
The first one is the button that you want to back up.
In the second there are paths that can be modified.
How to make a reference that after pressing the "backup" button will get a path of 2 forms.
The path is saved when I closed form2
I know how to do it in one form but unfortunately I can not refer to another form.
Source of Form 2:
Private Sub Browser_from1_Click(sender As Object, e As EventArgs) Handles Browser_from1.Click
Dim FolderBrowserDialog1 As New FolderBrowserDialog
FolderBrowserDialog1.ShowDialog()
TextBox1from.Text = FolderBrowserDialog1.SelectedPath
If Browser_from1.Text <> "" And TextBox1from.Text <> "" Then
Backup.StartCopy.Enabled = True
End If
End Sub
Private Sub Browser_to1_Click(sender As Object, e As EventArgs) Handles Browser_to1.Click
Dim FolderBrowserDialog1 As New FolderBrowserDialog
FolderBrowserDialog1.ShowDialog()
TextBox2to.Text = FolderBrowserDialog1.SelectedPath
If Browser_to1.Text <> "" And TextBox2to.Text <> "" Then
Backup.StartCopy.Enabled = True
End If
End Sub
Private Sub TextBox1from_TextChanged(sender As Object, e As EventArgs) Handles TextBox1from.TextChanged
End Sub
Private Sub save_settings_Click(sender As Object, e As EventArgs) Handles save_settings.Click
My.Settings.pathmem = TextBox2to.Text
My.Settings.pathmem1 = TextBox1from.Text
My.Settings.Save()
End Sub
Private Sub setting_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1from.Text = My.Settings.pathmem1
TextBox2to.Text = My.Settings.pathmem
End Sub
End Class
You dont want to create a reference to a form - that would (or could) create a whole new form. You want to hold onto the form reference.
This is done by passing a reference to the forms, but the talk of one form fiddling with the controls on another form is a bad idea because it breaks encapsulation. But forms are classes (it says so at the top of each one), so you can add Properties and Methods (Sub and/or Functions) to facilitate passing information back and forth.
Method One - Passing a Form Reference
The simplest way is to pass whatever the other form needs in the constructor:
' form 1 / "main" form / form to return to
Dim frm As New Form6(Me)
frm.Show()
Me.Hide()
In order for this to work, you need to modify the constructor (Sub New) on the destination form:
Private frmReturnTo As Form
Public Sub New(f As Form)
' This call is required by the designer.
InitializeComponent()
frmReturnTo = f
End Sub
It is best not to create your own constructor until you are familiar with them. Use the drop downs at the top of the code window: from the left pick the form name; from the right, select New. The designer adds required code to them which must not be changed.
Do not add any code before the InitializeComponent() call at least until you are familiar with the life cycle of a form. The form and its controls do not exist until that runs.
To return to the "main" form:
If frmReturnTo IsNot Nothing Then
frmReturnTo.Show()
End If
You may want to remove some of the title bar buttons or add code to the form Closing event to handle when the user closes via the system menu or buttons.
Using the constructor is ideal for cases where there is some bit of data which the form must have in order to do its job.
Method Two - Passing Data
Thats all well and good, but what about passing data to another form? You can use the constructor for that too. In order to pass say, a string, integer and a Point:
' destination / second form:
Public Sub New(a As String, b As Int32, c As Point)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Label1.Text = a
Label2.Text = b.ToString
Label3.Text = c.ToString
End Sub
Call it like this:
' method two: pass data you want to share in the ctor
Dim frm As New frmData("hello", 6, New Point(150, 550))
frm.Show()
Result:
Method Three: Properties
Thats fine, but if there is a lots of data that way can get cumbersome. Plus, you may want to update some of the data from the calling/main form. For this you can create Properties on the form to handle the data:
Public Property Label1Text As String
Get
Return Me.Label1.Text
End Get
Set(value As String)
Me.Label1.Text = value
End Set
End Property
Rather than a private variable to act as the backing field, one of the controls is used. The name leaves a bit to be desired as it exposes implementation details. So, use names which describe what the data represents rather than where it displays.
Public Property SpecialValue As Integer
Get
Return Integer.Parse(Me.Label2.Text)
End Get
Set(value As Integer)
Me.Label2.Text = value.ToString
End Set
End Property
Public Property SomePoint As Point
Get
Dim data = Me.Label3.Text.Split(","c)
Return New Point(Convert.ToInt32(data(0)),
Convert.ToInt32(data(1))
)
End Get
Set(value As Point)
Me.Label3.Text = value.X.ToString & "," & value.Y.ToString
End Set
End Property
A point was used just to show that other data types can be used. Setting those values from the calling/original/source form:
Using frm As New Form6
frm.Label1Text = "Ziggy"
frm.SpecialValue = 42
frm.SomePoint = New Point(111, 222)
frm.ShowDialog()
' do stuff here with any changes
Dim theint = frm.SpecialValue
End Using ' dispose of dialog
The destination controls would well have been TextBoxes for the user to edit. The Property "wrappers" allow you to fetch those values back, so in this case, a Dialog was used.
Method Four: Methods
You can also use methods as a way to pass data to the second/helper form. Here a List(of T) collection will be passed. In the child/display form a method is added to receive the data which it then displays. The task represented is proofing or viewing a filtered list:
Public Sub UpdateDisplay(lst As List(Of SimpleItem), filter As String)
DataGridView1.DataSource = lst
Label1.Text = String.Format("{0} Total {1} Items", lst.Count, filter)
End Sub
In the main/calling form:
' form level variable
Private frmDV As frmDataView
elsewhere...perhaps in a Click event:
' myList is a simple list of items
' Users pick which color to filter on via a combo box
Dim filter As String
If cboListFilter.SelectedItem IsNot Nothing Then
'Dim frmDV As New frmDataView
If frmDV Is Nothing OrElse frmDV.IsDisposed Then
frmDV = New frmDataView
End If
filter = cboListFilter.SelectedItem.ToString()
' apply the filter
Dim tmpList = myList.Where(Function(w) w.Color = filter).ToList()
frmDV.UpdateDisplay(tmpList, filter)
frmDV.Show()
Else
Return
End If
Result:
With DataBased apps a modified version of this can allow for the case where you display DataGridView data in detail form on another form. You need not have the second form rung SQL to add or update the record, and then the main form running another query to "refresh" the display. If the DataSource is a DataTable backed up by a fully configured DataAdapter, pass the DataTable and have the child form add, change or delete using that. The data will automagically be in the DataTable and DataGridView`.
There are other ways to do this, but they generally all boil down to passing something from A to B. Which way is "best" depends on what the app does, the use-case and the nature of the data. There is no one right way or best way.
For instance, Properties and in many cases Functions allow the B Form to close the feedback loop. With DB items, a DataChanged property might tell the calling form that data was added or changed so that form knows to use the DataAdapter to update the db.
'SECOND FORM
Public class secondForm (blah blah)
Public overloads property owner as myMainForm
'Must be only the form you prepared for that
Private sub secondForm_load(blah blah) handles blah blah
Texbox1.text=Owner.customcontrol.text
End sub
End class
'MAIN FORM
public class myMainForm(blah blah)
Private sub button1_click(blah blah) handles blah blah
Dim NewSecondForm as secondForm = New secondForm
NewSecondForm.owner(me)
NewSecondForm.show(me)
NewSecondForm.dispose()
' so you can have bidirectional communication between the two forms and access all the controls and properties from each other
End sub
End Class

Add data into new added row in `DataGridView` from `DataBindingSource`

In Form4 i have a DataGridView named DbTableDataGridView.
In Form3 there is a set of fields (text boxes) that are all bound to the DbTableBindingSource . When I run application the Form4 shows up. There is a button to open new form (Form3) and in there enter details about customers to be added as new row into database (DataGridView). My code for the "Add" button in Form4 looks like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.DbTableDataGridView.Refresh()
Me.DbTableBindingSource.AddNew()
Form3.ShowDialog()
Form3.ImiéTextBox.Text = ""
Form3.NazwiskoTextBox.Text = ""
Form3.Numer_TelefonuTextBox.Text = ""
Form3.Numer_RejestracyjnyTextBox.Text = ""
Form3.MarkaTextBox.Text = ""
Form3.ModelTextBox.Text = ""
Form3.Poj_SilnikaTextBox.Text = ""
Form3.RocznikTextBox.Text = ""
Form3.PaliwoTextBox.Text = ""
Form3.Data_PrzyjeciaDateTimePicker.Value = DateTime.Now
Form3.RichTextBox1.Text = ""
End Sub
It does add new row, selects it and clears entries in the text boxes (that are bound into 'DbTableBindingSource'.
In this form after I fill in all the fields I press button save:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Me.Validate()
Form4.DbTableBindingSource.EndEdit()
Me.DbTableTableAdapter.Update(CartronicDBDataSet.dbTable)
TableAdapterManager.UpdateAll(CartronicDBDataSet)
DbTableTableAdapter.Fill(Form4.CartronicDBDataSet.dbTable)
MsgBox("Saved")
Catch ex As Exception
MessageBox.Show("Blad zapisu. Sprobuj ponownie. W razie potrzeby zamknij, a nastepnie uruchom ponownie program Cartronic")
End Try
End Sub
It goes to the message "Saved" but actually does not fill in added new recently.
Any thoughts?
There is no link that I can see between Form3 and your data.
I'd recommend passing the newly created data row to a new instance of Form3.
Get the reference to your newly added row
Create a new Form3 (avoid default instance forms, they're ugly and evil). This will mean you don't need to clear the textboxes as you have a brand new form every time.
Pass the datarow into your form where you will bind it directly to the textboxes
Dim newRow = CType(Me.DbTableBindingSource.AddNew(), DataRow)
Using frmEditor As New Form3
frmEditor.DataSource = newRow
frmEditor.ShowDialog()
End Using
In form3 add the property (or preferably a constructor)
Private mDataSource As DataRow
Public Property DataSource As DataRow
Get
Return mDataSource
End Get
Set(value As DataRow)
mDataSource = value
Me.ImiéTextBox.DataBindings.Add("Text", mDataSource, "ImiéFieldName")
' ....
End Set
End Property
If you use this approach then you can get rid of all of the textbox clearing code.
I have done what you have suggested but little bit simpler.
Assigned all text boxes to each cell in current row as follows:
Form4.DbTableDataGridView.CurrentRow.Cells(5).Value = Me.NazwiskoTextBox.Text.ToString
Form4.DbTableDataGridView.CurrentRow.Cells(4).Value = Me.ImiéTextBox.Text.ToString
It works fine.
Cheers

Autofill TextBox/Checkbox from a previous TextBox' value (VB.NET Database)

Note: I'm using Visual Studio, original work was on SQL Server, moved to VB.NET
I have a Textbox "ViewStatusTxt", next to it there's a Button "ViewStatusBtn"
Below it there's a TextBox "ViewNAMETxt", another TextBox "ViewACTIVITYTxt" and then a Checkbox "ModifyStatusCB"
I'm trying to auto-fill the Checkbox AND the Textbox based on the ID input there, however I really have no clue about it since I'm new to VB.NET
Here's the code used
Private Sub IDSearch(StatusViewBtn As String)
' ADD SEARCH QUERY PARAMETERS - WITH WILDCARDS
SQL.AddParam("#StatusViewBtn", StatusViewBtn)
'RUN QUERY - SEARCH GIVES THOSE RESULTS
SQL.ExecQuery(" SELECT
aID,
Name,
Status,
Activity
FROM
[dbo].[initialTable]
WHERE
aID = #StatusViewBtn
ORDER BY
aID ASC")
End Sub
That's the function's code, which is fully working since it's a smaller version of the same one I used in a Search Page
Here's the button's function, which I'm sure is where I'm having problems, unless I need to add a specific function to the ViewNAMETxt
Private Sub StatusViewBtn_Click(sender As Object, e As EventArgs) Handles StatusViewBtn.Click
IDSearch(StatusViewBtn.Text)
ViewNAMETxt.Text = SQL.ExecQuery("SELECT
Name
FROM
initialTable
WHERE
aID = #StatusViewBtn")
End Sub
And I haven't even started on the Checkbox, viewing how the first one caused me issues. Hopefully the solution would be similar to both of them.
Thanks for reading guys, and sorry for the newbie question
1- Suppose you have a table named YourTable(int KeyColumn, string StringColumn, boolean BooleanColumn)
2- Create a form and put 2 textboxes and a checkbox and a button on it. KeyColumnTextBox, StringColumnTextBox, BooelanColumnCheckBox, SearchButton
3- In click event handler for SearchButton put the codes:
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim connection = New SqlConnection("Your Connection string here")
Dim command = New SqlCommand("SELECT StringColumn, BooleanColumn FROM YourTable WHERE KeyColumn=#KeyColumn", connection)
command.Parameters.Add(New SqlParameter("#KeyColumn", Int32.Parse(KeyColumnTextBox.Text)))
connection.Open()
Dim reader = command.ExecuteReader()
While reader.Read()
StringColumnTextBox.Text = reader.GetString(0)
BooleanColumnCheckBox.Checked = reader.GetBoolean(1)
End While
End Sub
Don't forget to Imports System.Data.SqlClient at top of your file.

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.