为什么我从System vb.net的列表框中获取System.Data.DataRowView"而不是实际值

问题描述:

有人可以帮忙吗?

我需要将数据库中的数据提取到VB.net的combolistbox中.我已经掌握了数据,但是现在发现第一行和"x"行需要从组合列表框中删除(它们是另一种软件的验证条目),因此不应为此应用程序选择它.

I need to extract data from a Database into a combolistbox in VB.net. I have got the data, but now find that The first and the 'x' line need to be removed from the combolistbox (they are validation entries for another software) and shouldn't be selected for this application.

我试图使用:-cbCubeARivet.Items.RemoveAt(index)从列表中删除有问题的条目,但是出现一个错误,让我知道我无法在数据源中使用"Items".

I tried to simply remove the offending entries from lists by using :- cbCubeARivet.Items.RemoveAt(index), but had an error letting me know I cannot use "Items" with a DataSource.

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

I decided to send the data to a listbox, and then try to transfer the entries to the combolistbox. This then lead me to getting multiple entries of System.Data.DataRowView in the combolist box. To demonstrate my problem I include an example code modified from 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

我可能没有得到正确的答案,所以在这里,以下内容使用模拟数据在ListBox和ComboBox中显示字符串,其中可通过强制转换获得整数当前项目作为DataRowView,访问Row,然后通过Row.Field(Of Integer)("ID")访问数据.

I may not get this correct so here goes, the following uses mocked up data to display a string in both a ListBox and ComboBox where a integer is available by casting the current item as a DataRowView, access Row then access the data via Row.Field(Of Integer)("ID").

在代码中,我为ComboBox使用了底层DataTable的副本,因为对列表框和组合框使用相同的数据表通常会在不需要时遍历.投射方面将在另一事件中完成,但希望保持简单.同样,我可能不在这里,请告诉我并可以进行调整以更好地适合您的问题.

In the code I use a copy of the underlying DataTable for the ComboBox as using the same data table for listbox and combobox will cause one to traverse when is generally unwanted. The cast aspect would be done in another event but wanted to stay simple. Again I may not be on track here, let me know and can adjust to better suit your question.

对Linq匿名语句使用Option Infer On的代码,也可以强类型键入.

Code using Option Infer On for the Linq anonymous statement which could be strongly typed too.

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