Hi there

More help required!

I have a table being imported into my VB application that has 3 columns. I have written code to import the table, and have written code to display on the first column (country) in a list view.

What I want to do now is have the user select / highlight an item in the list view, and have the third column (currency) related to that selected country appear in a text box when a button is clicked.

Here's the code I've written that successfully imports the data and displays the first column:

Private Sub frmCountry_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim dataCountry As New DataTable()
        Dim connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=E:\globexdata\globex.mdb"
        Dim sqlString As String = "SELECT * FROM countries"
        Dim dataAdapt As New OleDb.OleDbDataAdapter(sqlString, connectionString)

        dataAdapt.Fill(dataCountry)
        dataAdapt.Dispose()

        Dim qtyRows As Integer = dataCountry.Rows.Count

        For List = 0 To qtyRows - 1
            lstCountryview.Items.Add(dataCountry(List)(0))
        Next


    End Sub

Should I perhaps use something other than a list view?

Sorry to ask for help yet again, but I'm not used to struggling with IT stuff...yet when it comes to VB I've lost my computing mojo!!

Dani AI

Generated

Short answer: both of the solutions already posted are valid; pick the one that matches how you want the UI to behave. showed keeping a DataTable and using the selected index to look up the related field, and @Unhnd_Exception suggested attaching the currency to each ListViewItem (Tag or subitem). The index-mapping approach is simple but fragile if you ever sort or filter the view; the Tag/subitem approach keeps the currency tied to the visual item and is more robust when the UI order changes.

If you only need a single selectable list of country names and a textbox to show the currency, data-binding with a ListBox or ComboBox is cleaner than manual list population. It requires almost no bookkeeping: set the DataSource, use DisplayMember for country and ValueMember for currency, then read SelectedValue. That avoids keeping a separate global DataTable-to-ListView index mapping and reduces chances of bugs when you add sorting/filtering.

Example of the binding approach (use your actual column names):

' bind a ListBox to the DataTable
listCountries.DataSource = dataCountry
listCountries.DisplayMember = "Country"   ' column that contains the country name
listCountries.ValueMember = "Currency"   ' column that contains the currency

' read the currency safely
If listCountries.SelectedIndex >= 0 Then
    txtCurrency.Text = Convert.ToString(listCountries.SelectedValue)
End If

Practical cautions: if you stick with ListView+Tag, check Tag for Nothing or DBNull before calling ToString; if you use the index mapping, keep the DataTable in scope and avoid UI sorting that changes item order; prefer SelectedIndexChanged/SelectedValueChanged so the textbox updates immediately; set MultiSelect = False for single-selection scenarios; always dispose your DB objects after filling the DataTable.

Recommended Answers

All 3 Replies

Should I perhaps use something other than a list view

I don't think so.

Here's what you asked. Declare dataCountry as a global object so you can access it later. Private Sub InitView() has just settings for the ListView. You can take only settings and make them somewhere else without this sub. Last one is a button handler. I did assume that there's a one to one relationship between DataTable and the ListView. If you do any kind of sorting or things like that after moving the data from the datatable to listview, the code won't work.

Private dataCountry As New DataTable() ' Store data to a global DataTable

Private Sub InitView()
    ListView1.View = View.Details   ' Use ListView as a "datagrid"
    ListView1.MultiSelect = False   ' Only one row can be selected
    ListView1.HideSelection = False ' Selected row stays highlighted
    ListView1.FullRowSelect = True  ' The whole row is highlighted
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

    ' Check if a row is selected
    If ListView1.SelectedIndices.Count = 1 Then
        ' ListView1.SelectedIndices.Item(0) -> index of the selected row in the ListView
        ' dataCountry.Rows.Item(ListView1.SelectedIndices.Item(0)) -> the selected row in the DataTable
        ' dataCountry.Rows.Item(ListView1.SelectedIndices.Item(0)).Item(2) -> the second column of the selected row
        TextBox1.Text = dataCountry.Rows.Item(ListView1.SelectedIndices.Item(0)).Item(2).ToString()
    End If

End Sub

Instead of requiring user to press a button, I would use ListView's own event:

Private Sub ListView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.SelectedIndexChanged

    ' Check if a row is selected
    If ListView1.SelectedIndices.Count = 1 Then
        ' ListView1.SelectedIndices.Item(0) -> index of the selected row in the ListView
        ' dataCountry.Rows.Item(ListView1.SelectedIndices.Item(0)) -> the selected row in the DataTable
        ' dataCountry.Rows.Item(ListView1.SelectedIndices.Item(0)).Item(2) -> the second column of the selected row
        TextBox1.Text = dataCountry.Rows.Item(ListView1.SelectedIndices.Item(0)).Item(2).ToString()
    End If

End Sub

Now the TextBox reflects changes immediately when the user selects an item in the ListView.

HTH

Member Avatar for Member #857553

Here's another way that just stores the extra item in the listviewitem's tag.

You could also store it in a subitem.

For List = 0 To  dataCountry.Rows.Count - 1           
    lstCountryview.Items.Add(dataCountry(List)(0))
    'store the 3rd column in the tag or as a subitem
    lstCountryView.items(lstCountryview.items.count - 1).tag = dataCountry(List)(2)     
 Next


Private Sub lstCountryView_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstCountryView.SelectedIndexChanged

      If lstCountryView.SelectedItems.Count = 0 Then Exit sub

      'access the tag or subitem
      TextBox1.Text = lstCountryView.SelectedItems(0).Tag 
End Sub

Yes, Unhnd_Exception's solution is better. You don't need to keep DataTable and the list view is now sortable.

Tag-property is of type Object, so the line 14 should be: TextBox1.Text = ListView1.SelectedItems(0).Tag.ToString

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.