使用对象集合索引datagridview的边界

时间:2015-11-05 02:17:26

标签: vb.net datagridview

Ultranewbie来自vbnet。

因此在一个简单的代码上遇到了问题,但我无法弄清楚原因。

我在表单上有一个datagridview,在表单中定义了一个对象列表,我将它用作数据源。 因此,希望在表单加载时显示列,所以这样做:

Public Class Form1
Dim l As New List(Of Entities.Product)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.DataGridView1.AutoGenerateColumns = True
        Me.DataGridView1.DataSource = l
    End Sub

End class

它有效。

之后我加载列表中的对象并将其指定为数据源:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    For Each r As DataRow In d.Tables("table").Rows

        Dim p As New Entities.Product
        p.ID = r.Item("id")
        p.name = r.Item("name")
        p.prize = r.Item("prize")

        l.Add(p)

    Next

    Me.DataGridView1.AutoGenerateColumns = True
    Me.DataGridView1.DataSource = Nothing
    Me.DataGridView1.DataSource = l

End Sub

一切都按预期工作....直到我点击Datagridview中的一行。 然后我明白了:

An unhandled exception of type 'System.IndexOutOfRangeException' occurred in System.Windows.Forms.dll

Additional information: Index -1 does not have a value.

我还没有任何处理点击的代码......就好像它丢失了对绑定集合的引用。

我发现如果我删除Load事件中的行,我就没有问题....

任何人都可以解释为什么会这样?这是一个错误吗?

如果我将数据源分配给任何内容然后重新分配它应该重新加载,无论它在哪里分配到右边?

感谢您的投入。

丹尼尔

1 个答案:

答案 0 :(得分:0)

如果/当数据可以更改时,通用List(Of T)作为DataSource是次优的。

选项0

最初包含数据的DataTable会产生完美的功能DataSource。我不确定将数据复制到类型化列表是什么意思。

选项1 - BindingList(Of T)

Imports System.ComponentModel

' NVP is a simple Name-Value pairs class
Private NamePairs As BindingList(Of NVP)

    Private Sub FormLoad(....
        NamePairs = New BindingList(Of NVP)

        dgv.AutoGenerateColumns = True
        dgv.DataSource = NamePairs
        ...
    End Sub

    Private Sub Button1_Click(...
        NamePairs.Add(New NVP("ziggy", 42))
        NamePairs.Add(New NVP("zacky", 11))
        NamePairs.Add(New NVP("zoey", 2))
    End Sub

由于您没有进一步的英雄事迹,列表中的添加内容会自动显示在DGV中:

enter image description here

请注意,这仅监控列表内容的更改,而不是列表项目。如果您更改其中一个对象的NameValue,则更改不会自动显示。这将需要Type(类)实现INotifyPropertyChanged。当属性发生变化时,BindingList会将更改传递给它所绑定的控件。

选项2 - BindingSource

您可以使用BindingSource获得相同的结果,只需一步。

Private NamePairs As List(Of NVP)
Private BSPairs As BindingSource

Sub FormLoad.....
    NamePairs = New List(Of NVP)
    BSPairs = New BindingSource(NamePairs, Nothing)

    dgv.AutoGenerateColumns = True
    dgv.DataSource = BSPairs
End Sub

在点击事件中添加到列表中:

NamePairs.Add(New NVP("ziggy", 42))
NamePairs.Add(New NVP("zacky", 11))
NamePairs.Add(New NVP("zoey", 2))

BSPairs.ResetBindings(False)