Checkboxes are keeping myCurrencyManager.AddNew() from working properly - vb.net

I have a fully functional Windows forms app developed with a read-only datagridview bound to an Access DB.
Databound textboxes are used to edit fields. I then added 3 Checkbox fields to the DB, datagridview and the form. Then added chkName.DataBindings.Add("Checked", DBTable,"Field") just like the Textboxes. The checkboxes work properly displaying the correct data.
Only now when I try to add a row using myCurrencyManager.AddNew() it doesn't work. It does nothing except add a non-accessible row to the end of the datagridview. When I comment out the Checkbox DataBindings lines, everything works properly (without functioning checkboxes).
Any ideas what is wrong?
Here is the code:
Public Class frmRoutes
Dim RoutesConnection As OleDbConnection
Dim JS1Adapter As New OleDbDataAdapter
Dim JS1Table As New DataTable("JOBSITES")
Dim JSBS As BindingSource
Dim JS1State As String = "Edit"
Private Sub frmRoutes_Load(sender As Object, e As EventArgs) Handles MyBase.Load
RoutesConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source = C:\Microsoft\JS1TestDB.mdb")
RoutesConnection.Open()
Dim JobSitesCommand = New OleDbCommand _
("SELECT REF, STREET, CITY, SPEC, HELPER " +
"FROM Jobsites ORDER BY REF", RoutesConnection)
JS1Adapter.SelectCommand = JobSitesCommand
JS1Adapter.Fill(JS1Table)
JSBS = New BindingSource()
JSBS.DataSource = JS1Table
grdJobSites.DataSource = JSBS
txtRef.DataBindings.Add("Text", JSBS, "REF")
txtStreet.DataBindings.Add("Text", JSBS, "STREET")
txtCity.DataBindings.Add("Text", JSBS, "CITY")
'chkSpecial.DataBindings.Add("Checked", JSBS, "SPEC") 'THESE 2 CHECKBOX DATABINDINGS CAUSE THE 'ADDNEW' METHOD TO FAIL
'chkHelper.DataBindings.Add("Checked", JSBS, "HELPER")
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
Try
JSBS.AddNew()
Catch ex As Exception
MessageBox.Show("Error Adding a New row.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
JS1State = "Add"
End Sub
Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
JSBS.CancelEdit()
JS1State = "View"
End Sub
End Class

The issue is exactly as I already said: nullable data. I just tested this code (an actual minimal example):
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim table As New DataTable
With table.Columns
.Add("Name", GetType(String))
.Add("Flag", GetType(Boolean))
End With
With table.Rows
.Add("Peter", True)
.Add("Paul", False)
.Add("Mary", True)
End With
BindingSource1.DataSource = table
TextBox1.DataBindings.Add("Text", BindingSource1, "Name")
CheckBox1.DataBindings.Add("Checked", BindingSource1, "Flag")
End Sub
End Class
and an invalid cast exception occurred when adding a new row (via a BindingNavigator) because the Flag column contained DBNull.Value by default and that cannot be cast as type Boolean, which is required for the Checked property. There are two potential solutions. The best one depends on whether you might want to be able save null values or not.
If you don't want to save null values then specify a default Boolean value for that column. That would probably be False but may be True if you want it. That way, when a new row is added, that column already contains a Boolean value that is compatible with the Checked property. In my example, this:
.Add("Flag", GetType(Boolean))
becomes this:
.Add("Flag", GetType(Boolean)).DefaultValue = False
In your case, you'd have to get the appropriate column from the DataTable after populating it and set that property.
Set the ThreeState property of the CheckBox to True, bind to the CheckState property instead of the Checked property and do your own translation between nullable Boolean data in the data source and CheckState values in the control. Making that change to my example might look like this:
Public Class Form1
Private WithEvents checkStateBinding As Binding
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim table As New DataTable
With table.Columns
.Add("Name", GetType(String))
.Add("Flag", GetType(Boolean))
End With
With table.Rows
.Add("Peter", True)
.Add("Paul", False)
.Add("Mary", True)
End With
BindingSource1.DataSource = table
TextBox1.DataBindings.Add("Text", BindingSource1, "Name")
checkStateBinding = New Binding("CheckState", BindingSource1, "Flag")
CheckBox1.DataBindings.Add(checkStateBinding)
End Sub
Private Sub CheckStateBinding_Format(sender As Object, e As ConvertEventArgs) Handles checkStateBinding.Format
'Convert from nullable Boolean to CheckState.
If TryCast(e.Value, DBNull) Is DBNull.Value Then
e.Value = CheckState.Indeterminate
ElseIf CBool(e.Value) Then
e.Value = CheckState.Checked
Else
e.Value = CheckState.Unchecked
End If
End Sub
Private Sub CheckStateBinding_Parse(sender As Object, e As ConvertEventArgs) Handles checkStateBinding.Parse
'Convert from CheckState to nullable Boolean.
Select Case DirectCast(e.Value, CheckState)
Case CheckState.Indeterminate
e.Value = DBNull.Value
Case CheckState.Checked
e.Value = True
Case CheckState.Unchecked
e.Value = False
End Select
End Sub
End Class
The Binding raises its Format event when it needs to get data from the data source for the control and its Parse event when it needs to get data from the control for the data source. If types and/or values don't match up between the two, you can do your own translation.

Related

Coding navigation buttons using vb.net 2012

My main goal is to code navigation buttons to control records of a vb.net project connected with Microsoft Access Database. The four buttons included are First record, Last record, Next record and Previous record. The errors showing say "ShowData" and "CurrentRow" are not declared.
CurrentRow shows the following error correction options:
ShowData shows the following error correction options:
'to navigate to first record
Private Sub btn_first_Click(sender As Object, e As EventArgs) Handles btn_first.Click
CurrentRow = 0
ShowData(CurrentRow)
End Sub
'to navigate to last record
Private Sub btn_last_Click(sender As Object, e As EventArgs) Handles btn_last.Click
CurrentRow = Dst.Tables("Purchases_file").Rows.Count - 1
ShowData(CurrentRow)
End Sub
'to navigate to previous record
Private Sub btn_previous_Click(sender As Object, e As EventArgs) Handles btn_previous.Click
If CurrentRow <> 0 Then
CurrentRow -= 1
ShowData(CurrentRow)
Else
MsgBox("First record is reached!", MsgBoxStyle.Exclamation)
End If
End Sub
'to navigate to next record
Private Sub btn_next_Click(sender As Object, e As EventArgs) Handles btn_next.Click
If CurrentRow = Dst.Tables("Purchases_file").Rows.Count - 1 Then
MsgBox("Last record is reached!", MsgBoxStyle.Exclamation)
Else
CurrentRow += 1
ShowData(CurrentRow)
End If
End Sub
According to the error you get you did not declare CurrentRow before using it in the methods. Put
Private CurrentRow as Integer
in your class. ShowData calls the method to retrieve the data from the database. It should be something like this:
Private Sub ShowData(byval row as integer)
'code to get the data in the database
End Function
If the variable and method exist in another class of the project you need to reference them via their class. For example:
ClassName.CurrentRow
ClassName.ShowData(CurrentRow)
My Roasters table has field names of Name, City, and Zip. They are bond to labels on the BindingNavigator form and also a DataGridView. The BindingNavigator provides the buttons you describe.
Imports System.Data.SqlClient
Public Class BindingNavigator
Dim WithEvents bindSrc As New BindingSource
Private Sub BindingNavigator_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt = LoadData1()
bindSrc.DataSource = dt
BindingNavigator1.BindingSource = bindSrc
lblItem.DataBindings.Add(New Binding("Text", bindSrc, "Name"))
lblDescription.DataBindings.Add(New Binding("Text", bindSrc, "City"))
lblPrice.DataBindings.Add(New Binding("Text", bindSrc, "Zip"))
DataGridView1.DataSource = bindSrc
End Sub
Private Function LoadData1() As DataTable
Dim dt As New DataTable
Using conn As New SqlConnection(My.Settings.CoffeeConnection),
cmd As New SqlCommand("Select Top 10 * From Roasters;", conn)
conn.Open()
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
End Class

ifselectedindex changed , show data in a textbox

I've linked an access database to my form.
I have 1 table , 2 rows
1 = Researchtype short text
2 = Researchdetails (long text)
In my combobox1 i've binded my researchtype row so i can choose a type of research.
Question now: how can i bind the details data to the richtextbox below it in order to show the research data as soon as i choose a research type?
I've tried if else combos, try catch combos,
i'm thinking i'm actually overthinking the issue here.
What would be the easiest way to "select from dropdown" and show the result in textbox.
I'm a vb.net beginner
Public Class Onderzoeken
Private Sub Onderzoeken_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'PatientenDatabaseDataSetX.tbl_OnderzoeksTypes' table. You can move, or remove it, as needed.
Me.Tbl_OnderzoeksTypesTableAdapter.Fill(Me.PatientenDatabaseDataSetX.tbl_OnderzoeksTypes)
End Sub
Private Sub cboxOnderzoek_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboxOnderzoek.SelectedIndexChanged
If cboxOnderzoek.SelectedItem = Nothing Then
cboxOnderzoek.Text = ""
Else
rtbBeschrijvingOnderzoek.Text = CStr(CType(cboxOnderzoek.SelectedItem, DataRowView)("OZ_Onderzoeksbeschrijving"))
End If
End Sub
End Class
I added the entire code of that page now , it's not much, but as stated: I added the binding source and displaymember "researchtype" to the combobox.
So when i start the form, i can choose a type of research.
Now i need to show the description of the research in the richtextbox
In the Form.Load...
I have a function that returns a DataTable that contains columns called Name and Type. I bind the ComboBox to the DataTable and set the DisplayMember to "Name". Each Item in the ComboBox contains the entire DataRowView. I set the TextBox to the first row (dt(0)("Type")) Type column value so the correct information will be displayed for the initial selection.
I put the code to change the textbox display in ComboBox1.SelectionChangeCommitted because the other change events will produce a NRE since .SelectedItem has not yet been set when the form loads. The commited event will only occur when the user makes a selection.
First, cast the SelectedItem to its underlying type, DataRowView. Then you want the value of the Type column. This value is assigned to the text property of the textbox.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt = LoadCoffeeTable()
ComboBox1.DataSource = dt
ComboBox1.DisplayMember = "Name"
TextBox1.Text = dt(0)("Type").ToString
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
TextBox1.Text = DirectCast(ComboBox1.SelectedItem, DataRowView)("Type").ToString
End Sub
Just substitute Researchtype for Name and Researchdetails for Type.
After using 'OleDbDataAdapter' to fill the dataset, you can set 'DisplayMember' and 'ValueMember' for your ComboBox. Every time the index of your ComboBox changes, it's 'ValueMember' will be displayed in richtextbox.
Here's the code you can refer to.
Private dataset As DataSet = New DataSet()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connString As String = "your connection String"
Using con As OleDbConnection = New OleDbConnection(connString)
con.Open()
Dim cmd As OleDbCommand = New OleDbCommand()
cmd.Connection = con
cmd.CommandText = "SELECT Researchtype, Researchdetails FROM yourtable"
Dim adpt As OleDbDataAdapter = New OleDbDataAdapter(cmd)
adpt.Fill(dataset)
End Using
ComboBox1.DisplayMember = "Researchtype"
ComboBox1.ValueMember = "Researchdetails"
ComboBox1.DataSource = dataset.Tables(0)
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
RichTextBox1.Text = ComboBox1.SelectedValue.ToString()
End Sub
Result of my test.

Indicate combobox values with a specific ids?

I made a Sub that will populate my combobox with loan descriptions. I want to get the loancode of the loandescription on selectedindexchanged without querying again the database. Is this possible? Or should I query the database to get the indicated loancode?
Private Sub LoanProducts()
Using cmd As New SqlClient.SqlCommand("SELECT loancode,loandescription FROM LoanProducts", gSQlConn)
Dim dt As New DataTable
Dim da As New SqlClient.SqlDataAdapter
dt.Clear()
da.SelectCommand = cmd
da.Fill(dt)
For Each row As DataRow In dt.Rows
CmbLoanAvail.Items.Add(row("loandescription"))
Next row
End Using
End Sub
Expected output:
Everytime the combobox index changed, the loancode of the selected loandescription will be displayed to a textbox.
Set DataTable to combobox .DataSource property and populate .ValueMember and .DisplayMember properties with corresponding column names.
Private Sub LoanProducts()
Dim query As String = "SELECT loancode, loandescription FROM LoanProducts"
Using command As New SqlCommand(query, gSQlConn)
Dim data As New DataTable
Dim adapter As New SqlClient.SqlDataAdapter With
{
.SelectCommand = cmd
}
adapter.Fill(data)
CmbLoanAvail.ValueMember = "loancode"
CmbLoanAvail.DisplayMember = "loandescription"
CmbLoanAvail.DataSource = data
End Using
End Sub
You can use SelectionChangeCommitted event to execute some action when user made a selection
Private Sub comboBox1_SelectionChangeCommitted(
ByVal sender As Object, ByVal e As EventArgs) Handles comboBox1.SelectionChangeCommitted
Dim combobox As ComboBox = DirectCast(sender, ComboBox)
Dim selectedCode As String = combobox.SelectedValue.ToString() // returns 'loancode'
End Sub
If you could get DB rows as strongly typed classes, you could make use of ItemSource, DisplayMember and ValueMember, which would solve your problem.
In case you presented, you can use SelectedIndex property of ComboBox. Also, you need to store resultset in some class field (preferably Pirvate one). See example code below:
Public Class Form4
Private _result As DataTable
Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt As New DataTable
dt.Columns.Add("col1")
dt.Columns.Add("col2")
dt.Rows.Add("val11", "val12")
dt.Rows.Add("val21", "val22")
' at this point, we got our result from DB
_result = dt
For Each row As DataRow In dt.Rows
ComboBox1.Items.Add(row("col1"))
Next
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim selectedIndex = ComboBox1.SelectedIndex
Dim selectedRow = _result(selectedIndex)
End Sub
End Class
Keep your database objects local to the method where they are used so you can ensure that they are closed and disposed. Note the comma at the end of the first Using line. This includes the command in the same Using block.
Set the DataSource, DisplayMember and ValueMember after the Using block so the user interface code doesn't run until the connection is disposed.
To get the loan code you simply access the SelectValue of the ComboBox.
Private Sub LoanProducts()
Dim dt As New DataTable
Using gSqlConn As New SqlConnection("Your connection string"),
cmd As New SqlClient.SqlCommand("SELECT loancode,loandescription FROM LoanProducts", gSqlConn)
gSqlConn.Open()
dt.Load(cmd.ExecuteReader)
End Using
ComboBox1.DataSource = dt
ComboBox1.DisplayMember = "loandescription"
ComboBox1.ValueMember = "loancode"
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As Object, ByVal e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
MessageBox.Show($"The Loan Code is {ComboBox1.SelectedValue}")
End Sub

Datagridview drag&drop rows when using datasource

I'm trying to get my first application up and running, but i'm struggling with drag and drop operations in the datagridview control.
I have created a datagrid view that has a datasource connected to it.
Public oBodyAssembly As New BindingList(Of BodyComponent)
DataGridView1.DataSource = oBodyAssembly
In this DataSource the users creates new objects and these are displayed in the datagridview. To allow the user to correct or alter his initial order of adding objects I would like to have them drag and drop rows to rearrange the position of the objects in the grid and also in the DataSource.
I have tried this example code I have found written in C# and altered it to VB.NET, it works in the fact that I can determinate the row I drag and determinate the position of the drop.
Link to the example code
But then the code in the sample inserts a new row and removes the old. This doesn't work for me. The removing works fine, and the object is also deleted from my DataSource. The inserting of the new row on the other hand doesn't.
My datasource is a BindingList(Of BodyComponent) It only contains object that are derived from the BodyComponent class.
How can I get this operation to work? I'm stuck..
Here is the code I have so far for the drag and drop operation.
Public oRowIndexMouseDown As Integer
Public oRow As DataGridViewRow
Private Sub BodyAssemblyDrag_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles DataGridView1.MouseDown
If DataGridView1.SelectedRows.Count = 1 Then
If e.Button = MouseButtons.Left Then
oRow = DataGridView1.SelectedRows(0)
oRowIndexMouseDown = DataGridView1.SelectedRows(0).Index
'Debug.Print("Row to move = " & oRowIndexMouseDown)
DataGridView1.DoDragDrop(sender, DragDropEffects.Move)
End If
End If
End Sub
Private Sub BodyAssemblyDrag_dragenter(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragEnter
If DataGridView1.SelectedRows.Count = 1 Then
e.Effect = DragDropEffects.Move
End If
End Sub
Private Sub BodyAssemblyDrag_dragdrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragDrop
Dim oPoint As Point
oPoint = DataGridView1.PointToClient(New Point(e.X, e.Y))
Dim oRowIndexMouseDrop As Integer
oRowIndexMouseDrop = DataGridView1.HitTest(oPoint.X, oPoint.Y).RowIndex
'Debug.Print("Drop row # " & oRowIndexMouseDrop)
If Not oRowIndexMouseDrop = oRowIndexMouseDown Then
'DataGridView1.Rows.RemoveAt(oRowIndexMouseDown)
'DataGridView1.Rows.Insert(oRowIndexMouseDrop, oRow)
End If
End Sub
Screenshot of winform
Add: method of creating objects in the list.
Public oBodyAssembly As New List(Of BodyComponent)
Private Sub BTN_BODY_ADD_CILINDER_Click(sender As Object, e As EventArgs) Handles BTN_BODY_ADD_CILINDER.Click
' Create a new cylinder and add it into the oBodyAssembly
Dim oCylinder As New Body_Cylinder
oBodyAssembly.Add(oCylinder)
' Set the index number for this cylinder
oCylinder.Index = oBodyAssembly.Count
' Set the component type
oCylinder.Type = BodyComponent.BodyComponentType.Cylinder
End Sub
Private Sub BTN_BODY_ADD_CONE_Click(sender As Object, e As EventArgs) Handles BTN_BODY_ADD_CONE.Click
' Create a new cone and add it into the oBodyAssembly
Dim oCone As New Body_Cone
oBodyAssembly.Add(oCone)
' Set the index number for this cylinder
oCone.Index = oBodyAssembly.Count
' Set the component type
oCone.Type = BodyComponent.BodyComponentType.Cone_reduction
End Sub
Classes:
Public Class BodyComponent
' Basic properties that are required for all of the bodycompenents
' regardless of the type.
Public Property Index() As Double
Public Property Type() As BodyComponentType
Public Property Height() As Double
Public Property Thickness() As Double
Public Property Elevation() As Double
Private Property Mass() As Double
' Type Enum that defines what kind of body component is created.
Public Enum BodyComponentType
Cylinder = 0001
Cone_reduction = 0002
End Enum End Class
Derived object ( same for cone )
Public Class Body_Cylinder
' Get the base properties
Inherits BodyComponent
' Set new properties that are only required for cylinders
Public Property Segments() As Integer
Public Property LW_Orientation() As Double End Class
First, since a BindingList cannot be sorted or ordered (without recreating the whole collection), I would use a simple List(Of T) with a BindingSource:
' Form level declarations:
Private Animals As List(Of AnimalEx)
Private BSAnimal As BindingSource
Then, once the list is created:
Animals = New List(Of AnimalEx)
' add Animals aka BodyComponent objects, then...
BSAnimal = New BindingSource(Animals, Nothing)
dgv.DataSource = BSAnimal
You will have to learn some new methods to manage the data. Since now, the List holds the data but the BindingSource provides the binding capabilities, some things you do to the List and some thru the BindingSource.
As for the row drag-drop, the code in this answer is a nice starting point, but there are a few things lacking. It doesnt account for a) A bound DGV, b) Users trying to drag the NewRow, c) users clicking on Non-Row areas of the DGV (empty/open portions) d) Allow the mouse to do other things like resize columns. I fixed those, but there may be other mouse ops to exempt.
' Form-level declarations
Private fromIndex As Integer = -1
Private bMouseDn As Boolean = False
Private MouseDnPt As Point = Point.Empty
Private Sub dgv_DragOver(sender As Object, e As DragEventArgs) Handles dgv.DragOver
e.Effect = DragDropEffects.Move
End Sub
Private Sub dgv_MouseDown(sender As Object, e As MouseEventArgs) Handles dgv.MouseDown
bMouseDn = (e.Button = Windows.Forms.MouseButtons.Left)
End Sub
Private Sub dgv_MouseMove(sender As Object, e As MouseEventArgs) Handles dgv.MouseMove
If bMouseDn Then
' first time, just grab the start location
If (MouseDnPt = Point.Empty) Then
MouseDnPt = e.Location
Exit Sub
End If
End If
If bMouseDn AndAlso MouseDnPt <> Point.Empty Then
Dim hitTst = dgv.HitTest(e.X, e.Y)
If hitTst IsNot Nothing AndAlso fromIndex = -1 AndAlso hitTst.RowIndex > -1 Then
fromIndex = hitTst.RowIndex
If dgv.Rows(fromIndex).IsNewRow = False Then
dgv.DoDragDrop(dgv.Rows(fromIndex), DragDropEffects.Move)
End If
End If
End If
End Sub
Private Sub dgv_MouseUp(sender As Object, e As MouseEventArgs) Handles dgvDD.MouseUp
If bMouseDn AndAlso (e.Button = Windows.Forms.MouseButtons.Left) Then
bMouseDn = False
End If
End Sub
I used a simple Point in place of the Rectangle, it tests for non-row area clicks and only begins to drag when the mouse moves and has the left button down. It also declines to DragDrop the NewRow.
Like the original version, it is dragging a DataGridViewRow. But since we want (must) change the DataSource, not the DGV rows, we have to get the item back from the DataSource:
Private Sub dgv_DragDrop(sender As Object, e As DragEventArgs) Handles dgv.DragDrop
Dim p As Point = dgv.PointToClient(New Point(e.X, e.Y))
Dim dragIndex = dgv.HitTest(p.X, p.Y).RowIndex
If (e.Effect = DragDropEffects.Move) Then
' cast to a row
Dim dragRow As DataGridViewRow = CType(e.Data.GetData(GetType(DataGridViewRow)),
DataGridViewRow)
' get related Animal object
Dim a As AnimalEx = CType(dragRow.DataBoundItem, AnimalEx)
' manipulate DataSource:
BSAnimal.RemoveAt(fromIndex)
BSAnimal.Insert(dragIndex, a)
' if the DGV is SingleSelect, you may want:
'dgv.Rows(dragIndex).Selected = True
' we are done dragging
bMouseDn = False
fromIndex = -1
MouseDnPt = Point.Empty
End If
End Sub
Result:
The "non row" area mentioned is the yellowish areas.

Pass variable to new form with Datatable and Listbox

I am currently trying to write an application like address book. Listbox works properly, it shows everything corretly. But I need to pass id of chosen listbox item to another form. I got code like this in Form2:
Private myTable As New DataTable()
Public Sub LoadXml(sender As Object, e As EventArgs) Handles Me.Load
With myTable.Columns
.Add("DisplayValue", GetType(String))
.Add("HiddenValue", GetType(Integer))
End With
myTable.DefaultView.Sort = "DisplayValue ASC"
ListBox1.DisplayMember = "DisplayValue"
ListBox1.ValueMember = "HiddenValue"
ListBox1.DataSource = myTable
Dim doc As New Xml.XmlDocument
doc.Load("c:\address.xml")
Dim xmlName As Xml.XmlNodeList = doc.GetElementsByTagName("name")
Dim xmlSurname As Xml.XmlNodeList = doc.GetElementsByTagName("surname")
Dim xmlId As Xml.XmlNodeList = doc.GetElementsByTagName("id")
For i As Integer = 0 To xmlName.Count - 1
Dim nazwa As String = xmlName(i).FirstChild.Value + " " + xmlSurname(i).FirstChild.Value
myTable.Rows.Add(nazwa, xmlId(i).FirstChild.Value)
MsgBox(myTable.Rows(i).Item(1).ToString)
Next i
ListBox1.Sorted = True
End Sub
Later in the code I have event:
Public Sub ListBox1_DoubleClick(sender As Object, e As EventArgs) Handles ListBox1.DoubleClick
End Sub
I would like to know how can I call id from DataTable for selected listbox item. I hope u understand what I mean since my english is not perfect :)
Since you have added the XML value id to the data table column HiddenValue and you have assigned HiddenValue as the ValueMember for the listbox, once a record is selected in the listbox, id will be available in the listbox's [SelectedValue][1] member. For example:
Public Sub ListBox1_DoubleClick(sender As Object, e As EventArgs) Handles ListBox1.DoubleClick
MsgBox("Selected Id: " & ListBox1.SelectedValue.ToString())
End Sub