向DataGridView添加新行时,ListChanged ItemAdded事件触发两次

时间:2019-02-27 05:30:09

标签: .net vb.net winforms bindingsource

我有一个简单的数据表设置,连接到它的BindingSource和绑定到BindingSource的DataGridView。 DataTable填充了1个初始行。然后,我开始听BindingSource.Listchanged事件。

当我开始在DataGridView中编辑新行时,将触发具有ItemAdded类型的ListChanged事件。 BindingSource有2个项目,添加的项目是具有默认值的行。如果取消编辑,则会收到ListChanged ItemDeleted事件,到目前为止,这是合乎逻辑的。

但是,如果我输入新行,我将仅收到另一个ItemAdded通知,并且BindingSource再次包含2个项目。因此,我有两个 ItemAdded事件,但是只有一个项目被添加到BindingSource的基础列表中。

我现在要做的是跟踪BindingSource列表计数,如果没有更改,我将ItemAdded事件视为“ ItemReplace”事件。但是我想知道什么是处理这种情况的正确方法。

我附上了用于跟踪此事件的代码。

Imports System.ComponentModel

Public Class Form1
    Dim bs As New BindingSource
    Dim dt As New DataTable

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        AddHandler bs.ListChanged, AddressOf OnListChanged
        dt.Columns.Add("ID")
        dt.Columns.Add("Name")
        dt.Rows.Add("1", "Line 1")
        bs.DataSource = dt
        DataGridView1.DataSource = bs
    End Sub

    Private Sub OnListChanged(ByVal sender As Object, ByVal e As ListChangedEventArgs)

        Select Case e.ListChangedType
            Case ListChangedType.ItemAdded
                TextBox1.Text += String.Format("ItemAdded Count:{0} NewIndex:{1}{2}", bs.List.Count, e.NewIndex, vbCrLf)
            Case ListChangedType.ItemDeleted
                TextBox1.Text += String.Format("ItemDeleted Count:{0} NewIndex:{1}{2}", bs.List.Count, e.NewIndex, vbCrLf)
            Case ListChangedType.ItemChanged
                TextBox1.Text += String.Format("ItemChanged Count:{0} NewIndex:{1}{2}", bs.List.Count, e.NewIndex, vbCrLf)
            Case ListChangedType.ItemMoved
                TextBox1.Text += String.Format("ItemMoved Count:{0} NewIndex:{1}{2}", bs.List.Count, e.NewIndex, vbCrLf)
            Case ListChangedType.Reset
                TextBox1.Text += String.Format("Reset Count:{0} NewIndex:{1}{2}", bs.List.Count, e.NewIndex, vbCrLf)
        End Select
    End Sub
End Class

更新微软在IBindingList上的docs中为两次射击提供了一些启示:

  

调用此方法时,应引发一个ListChanged事件,其中ItemAdded枚举带有适当的索引。添加的行处于以下状态:在DataGridView控件上单击Esc可以删除新行。在该行上用 second 时间引发具有ItemAdded枚举的ListChanged事件,表明该项目现在是普通行(不在新状态)。

因此,逻辑似乎是,在第一个ItemAdded通知之后,您将收到第二个ItemAdded通知(意味着保留该项目)或ItemDeleted通知(意味着丢弃先前添加的项目)。

但是问题是,当我使用ReadXML方法将数据加载到绑定的DataTable时,ListChanged事件每行仅引发一次。

一些测试表明,如果所添加项目的IsNew属性为true,则它是一个临时项目。这就是我可以从final分辨临时数据的方法。

0 个答案:

没有答案