【问题标题】:selecting from a combo box with data from csv in vb.net从带有来自 vb.net 中 csv 数据的组合框中进行选择
【发布时间】:2016-07-20 11:24:50
【问题描述】:

我有一个 .csv 文件,我将其加载到数据网格视图内的组合框中。我的 csv 是这样的:

prodname,prodcode,amt
prodname1,prodcode1,amt1
prodname2,prodcode2,amt2

prodname 是我在 datagridview 内的组合框中显示的内容。

我想要的是当我选择prodname1prodcode1amt1 时将显示在数据网格视图的同一行上。我刚刚开始在 vb.net 中摸索,如果有人帮助我,我将不胜感激。

这是我现在拥有的:

    Dim cmb As New DataGridViewComboBoxColumn()
    cmb.HeaderText = "Product Name"
    cmb.Name = "cmb"
    DataGridView2.Columns.Add(cmb) 'code for a combobox column in datagridview

    Dim filename As String
    Dim dt As New DataTable
    filename = "/file/path/here"
    Dim sr As New IO.StreamReader(filename)

    Dim newline() As String = sr.ReadLine.Split(","c)
    dt.Columns.AddRange({New DataColumn(newline(0)), _
                         New DataColumn(newline(1))})
    While (Not sr.EndOfStream)
        newline = sr.ReadLine.Split(",")
        Dim newrow As DataRow = dt.NewRow
        cmb.Items.Add(newline(0))
        newrow.ItemArray = {newline(1)}
        dt.Rows.Add(newrow)
    End While
    DataGridView2.DataSource = dt

更新:

我根据 Alex 的回答更新了我的代码,但仍然出现错误。

    Dim cmb As New DataGridViewComboBoxColumn()
    cmb.HeaderText = "Product Name"
    cmb.Name = "cmb"
    DataGridView1.Columns.Add(cmb)

    AddHandler DataGridView1.CellValueChanged, AddressOf DataGridView1_OnCellValueChanged
    AddHandler DataGridView1.CurrentCellDirtyStateChanged, AddressOf DataGridView1_OnCurrentCellDirtyStateChanged

    Dim filename As String

    filename = "/path/to/file"
    Dim sr As New IO.StreamReader(filename)

    Dim newline() As String = sr.ReadLine.Split(","c)
    dt.Columns.AddRange({New DataColumn(newline(0)), _
    New DataColumn(newline(1))})

     While (Not sr.EndOfStream)
        newline = sr.ReadLine.Split(","c)
        Dim newrow As DataRow = dt.NewRow
        cmb.Items.Add(newline(0))
        'newrow.ItemArray = {newline(1)} 
        dt.Rows.Add(newrow)
        dicItems.Add(newline(0), newline.Skip(1))
    End While
    DataGridView1.DataSource = dt
End Sub

Private Sub DataGridView1_OnCellValueChanged(ByVal s As Object, ByVal e As DataGridViewCellEventArgs)
    If e.ColumnIndex = 0 Then
        Dim changedCell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex)
        For i As Integer = 0 To dt.Columns.Count
            dt.Rows(e.RowIndex).Item(i) = dicItems(changedCell.Value.ToString)(i) **error here**
        Next
    End If
End Sub

Private Sub DataGridView1_OnCurrentCellDirtyStateChanged(ByVal s As Object, ByVal e As EventArgs)
    If DataGridView1.IsCurrentCellDirty Then
        DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
    End If
End Sub
  • 他在他的样本上使用了分号,但我坚持使用逗号。 :)

错误显示Cannot find column 2,或者当我调整某些内容时,错误在同一行变成The given key was not present in the dictionary

【问题讨论】:

    标签: vb.net csv datagridview


    【解决方案1】:

    您需要两个新的事件处理程序:

    AddHandler DataGridView1.CellValueChanged, AddressOf DataGridView1_OnCellValueChanged
    AddHandler DataGridView1.CurrentCellDirtyStateChanged, AddressOf DataGridView1_OnCurrentCellDirtyStateChanged
    

    首先是识别组合框的单元格值是否已更改。 后者是在您单击组合框项目时触发OnCellValueChanged(默认行为是该事件仅在您离开单元格后触发)。 将该代码放入 Forms 构造函数或 Load 事件处理程序中。

    此外,您必须存储哪个prodname 具有哪些详细信息(例如prodname1 => prodcode1,amt1)。在我的示例中,我使用 Dictionary<Key: string => Values: IEnumerable<string> 进行了此操作。

    Class Form1
       Private dicItems As New Dictionary(Of String, IEnumerable(Of String))
       Private dt As New DataTable
       ...
       Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
         While (Not sr.EndOfStream)
            newline = sr.ReadLine.Split(","c)
            Dim newrow As DataRow = dt.NewRow
            cmb.Items.Add(newline(0))
            dt.Rows.Add(newrow)
            'Fill Dicitonary here. Key: newLine(0), values: newLine(1,2,...n)
            dicItems.Add(newline(0), newline.Skip(1))
         End While
       End Sub
    

    事件处理程序的代码非常简单:

      Private sub DataGridView1_OnCurrentCellDirtyStateChanged(s As Object, e As EventArgs)
            If DataGridView1.IsCurrentCellDirty Then
                 DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
            End If
         End sub
    

    => 通过提交当前组合框项更改触发CellValueChangedEvent

    Private sub DataGridView1_OnCellValueChanged(s As Object, e As DataGridViewCellEventArgs)
        If e.ColumnIndex = 0 Then
            Dim changedCell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex)
            For i As Integer = 0 To dt.Columns.Count 
                dt.Rows(e.RowIndex).Item(i) = dicItems(changedCell.Value.ToString)(i)
            Next        
        End If
    End sub
    

    => 检查组合框是否已更改 (ColumnIndex = 0) 并获取更改的单元格。
    在字典中查找与给定键 (prodname) 对应的 prodcode,amt
    DataTable 中设置新值(您必须将dt 设为类字段而不是Load 方法中的变量)。

    【讨论】:

    • 你好!感谢您的答复。但是我有后续问题,这段代码给了我一个警告newline.Skip(1),当我运行程序时,我的 dgv 中没有显示任何内容。第二,The given key was not present in the dictionary. 当我在组合框中选择某些内容时。是这条线dt.Rows(e.RowIndex).Item(i) = dict(changedCell.Value.ToString)(i)
    • 好的,我想出了 newline.skip 部分。这个还是有错误的。 The given key was not present in the dictionary.
    • 在这种情况下,changedCell 有一个您之前没有添加到字典中的值。在dicItems.Add(newline(0), newline.Skip(1))changedCell.Value.ToString 中放置断点以查看发生了什么。也许您的文本文件中有一个空行?顺便说一句,使用您在问题中提供的演示数据,我没有收到任何错误。
    • 另外:我删除了 newrow.ItemArray = {newline(1)} 行,因为它不是必需的。检查您是否也将其删除。
    • 是的,我确实删除了它。我确实表明我正在使用 .csv 文件。有什么不同吗,因为我认为您使用的是文本文件?
    猜你喜欢
    • 2021-08-07
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多