为什么我从vb.net中的Listbox获取System.Data.DataRowView“而不是实际值

时间:2016-01-06 16:54:21

标签: sql vb.net listbox

有人可以帮忙吗?

我需要将数据从数据库中提取到VB.net中的combolistbox中。我有数据,但现在发现第一个和' x'需要从combolistbox中删除行(它们是另一个软件的验证条目),并且不应该为此应用程序选择。

我试图通过使用以下命令从列表中删除有问题的条目: - cbCubeARivet.Items.RemoveAt(index),但有一个错误让我知道我不能使用" Items"使用DataSource。

我决定将数据发送到列表框,然后尝试将条目传输到combolistbox。然后,这导致我在组合框中获取System.Data.DataRowView的多个条目。为了演示我的问题,我提供了一个从MSDN修改的示例代码。

Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Collections
Imports System.Data.SqlClient

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        ' Populate the list box using an array as DataSource. 
        Dim SQLConnectionString As String = "Data Source=HL605\RIVWARE;Database=RIVWARE;Integrated Security=true;"
        Dim mySQLConnection As New SqlConnection(SQLConnectionString)
        mySQLConnection.Open()
        Dim SQLDataTable As New System.Data.DataTable

        'Create new DataAdapter
        'Use DataAdapter to fill DataTable
        Dim mySQLDataAdapter = New SqlDataAdapter("SELECT * FROM [Rivware].[dbo].[RivetTypes]", mySQLConnection)
        mySQLDataAdapter.Fill(SQLDataTable)
        ListBox1.DataSource = SQLDataTable
        ListBox1.DisplayMember = "RivetType"


        'original code from MSDN
        'Dim USStates As New ArrayList()
        'USStates.Add(New USState("Alabama", "AL"))
        'USStates.Add(New USState("Washington", "WA"))
        'USStates.Add(New USState("West Virginia", "WV"))
        'USStates.Add(New USState("Wisconsin", "WI"))
        'USStates.Add(New USState("Wyoming", "WY"))
        'ListBox1.DataSource = USStates

        ' Set the long name as the property to be displayed and the short
        ' name as the value to be returned when a row is selected.  Here
        ' these are properties; if we were binding to a database table or
        ' query these could be column names.

        ' Bind the SelectedValueChanged event to our handler for it.
        AddHandler ListBox1.SelectedValueChanged, AddressOf ListBox1_SelectedValueChanged

        ' Ensure the form opens with no rows selected.
        ListBox1.ClearSelected()
    End Sub 'NewNew

    Private Sub ListBox1_SelectedValueChanged(ByVal sender As Object, ByVal e As EventArgs)
        If ListBox1.SelectedIndex <> -1 Then
            TextBox1.Text = ListBox1.SelectedValue.ToString()
            ' If we also wanted to get the displayed text we could use
            ' the SelectedItem item property:
            ' Dim s = CType(ListBox1.SelectedItem, USState).LongName
        End If

    End Sub
End Class 'ListBoxSample3

Public Class USState
    Private myShortName As String
    Private myLongName As String

    Public Sub New(ByVal strLongName As String, ByVal strShortName As String)
         Me.myShortName = strShortName
         Me.myLongName = strLongName
    End Sub 'NewNew

    Public ReadOnly Property ShortName() As String
        Get
            Return myShortName
        End Get
    End Property
    Public ReadOnly Property LongName() As String
        Get
            Return myLongName
        End Get
    End Property
End Class 'USState

2 个答案:

答案 0 :(得分:0)

我可能不会这样正确所以这里,以下使用模拟数据在ListBox和ComboBox中显示一个字符串,其中通过将当前项目转换为DataRowView可获得整数,访问Row然后通过访问数据Row.Field(Of Integer)(“ID”)。

在代码中,我使用ComboBox的基础DataTable的副本,因为对于listbox使用相同的数据表,并且当通常不需要时,组合框将导致一个遍历。演员方面将在另一场比赛中完成,但希望保持简单。我可能不会在这里走上正轨,让我知道并且可以调整以更好地适应您的问题。

使用Option Infer On的代码,用于Linq匿名语句,也可以强类型化。

Dim dt As New DataTable
dt.Columns.Add(New DataColumn With {.ColumnName = "ID", .DataType = GetType(Integer)})
dt.Columns.Add(New DataColumn With {.ColumnName = "Name", .DataType = GetType(String)})

Dim data =
    (
        From M In System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.MonthNames
        Where Not String.IsNullOrEmpty(M)).ToList.Select(
        Function(monthName, index) New With
            {
                .ID = index, .Name = monthName
            }
    ).ToList
For Each item In data
    dt.Rows.Add(New Object() {item.ID, item.Name})
Next

ListBox1.DataSource = dt
ListBox1.DisplayMember = "Name"

ComboBox1.DataSource = dt.Copy
ComboBox1.DisplayMember = "Name"

Dim theTable As DataTable = CType(ComboBox1.DataSource, DataTable)
Dim theRow As DataRow = theTable.AsEnumerable _
        .Where(
            Function(row) row.Field(Of String)("Name") = "September") _
        .FirstOrDefault()

If theRow IsNot Nothing Then
    theTable.Rows.Remove(theRow)
End If

答案 1 :(得分:0)

再次感谢@Karen Payne,

我用你的代码引导我朝着正确的方向前进。

我创建了一个新的应用程序并添加了一个文本框和两个Listbox,然后粘贴代码。要运行,您需要指向自己的服务器,数据库和表。

这就是我想出的。它很有用,因为它会以可用的形式提供实际数据: -

Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Collections
Imports System.Data.SqlClient

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' get the data
        Dim SQLConnectionString As String = "Data Source=HL605\RIVWARE;Database=RIVWARE;Integrated Security=true;"
        Dim mySQLConnection As New SqlConnection(SQLConnectionString)

        ' Populate the list box using an array as DataSource. 
        mySQLConnection.Open()
        Dim SQLDataTable As New System.Data.DataTable

        'Create new DataAdapter
        Dim mySQLDataAdapter = New SqlDataAdapter("SELECT * FROM [Rivware].[dbo].[RivetTypes]", mySQLConnection)
        mySQLDataAdapter.Fill(SQLDataTable)
        ListBox1.DataSource = SQLDataTable
        ListBox1.DisplayMember = "RivetType"

        ' remove validation data from list
        Dim Count As Integer
        Dim X As Integer
        'get the column of data to search for
        For Count = 0 To ListBox1.DataSource.Columns.Count - 1
            X = InStr(ListBox1.DataSource.Columns.Item(Count).ToString, "Name")
            If X <> 0 Then Exit For
        Next
        ' now search for any invalid rows, in that column. those containing "---"
        Dim TheTable As DataTable = CType(ListBox1.DataSource, DataTable)
        Dim theRow As DataRow() = TheTable.Select()
        Dim RowNumber As Integer
        For RowNumber = 0 To UBound(theRow) - 1
            If theRow(RowNumber).Item(Count).ToString <> "---" Then
                ' data is OK so transer it to the other listbox
                ListBox2.Items.Add(theRow(RowNumber).Item(Count - 1).ToString)
            End If
        Next

        ListBox2.ClearSelected()
    End Sub 'NewNew

    Private Sub ListBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox2.SelectedIndexChanged
        TextBox1.Text = ListBox2.SelectedItem.ToString()
    End Sub
End Class 'ListBoxSample3