Событие ListChanged ItemAdded запускается дважды при добавлении новой строки в DataGridView. - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть простая настройка DataTable, подключенного к нему BindingSource и DataGridView, привязанного к BindingSource.DataTable заполняется 1 исходной строкой.Затем я начинаю слушать событие BindingSource.Listchanged.

Когда я начинаю редактировать новую строку в DataGridView, запускается событие ListChanged с типом ItemAdded.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

ОБНОВЛЕНИЕ Microsoft проливает некоторый светпри двойном срабатывании в его документах на IBindingList:

Когда этот метод вызывается, вы должны вызвать событие ListChanged с перечислением ItemAdded, содержащим соответствующий индекс.Добавленная строка находится в состоянии, при котором нажатие клавиши Esc на элементе управления DataGridView может удалить новую строку.Возникновение события ListChanged с перечислением ItemAdded a секунда время в этой строке указывает, что элемент теперь является обычной строкой (не в новом состоянии).

Так что это выглядит как логикаявляется то, что после первого уведомления ItemAdded вы получите либо второе уведомление ItemAdded (означает сохранить элемент), либо уведомление ItemDeleted (означает сброс ранее добавленного элемента).

Но проблема в том, что когда я загружаю данные в связанный DataTable с помощью метода ReadXML, событие ListChanged вызывается только один раз для строки.

Некоторые тесты показывают, что свойство IsNew добавленного элемента имеет значениеправда, тогда это временный пункт.Так я могу отличить временные данные от окончательных.

...