Держите DataGridView BindingSource от обновления значений ячеек определенного столбца - PullRequest
1 голос
/ 21 марта 2019

У меня есть DataGridView, который связан с DataTable с использованием BindingSource, и не все столбцы в DataGridView связаны со свойствами этого DataSource.Чтобы быть более конкретным, у меня есть пользовательский DataGridViewColumn для множественного выбора, который является производным от класса DataGridViewCheckBoxColumn и имеет главный флажок, который управляет другими элементами, расположенными в заголовке столбца.Моя проблема в том, что всякий раз, когда вызывается DataTable.AcceptChanges, DataGridViewCheckBoxCell возвращается к его значению по умолчанию (False), и я теряю свой предыдущий выбор.Кто-нибудь знает хороший способ предотвратить или отодвинуть это поведение в сторону?

По сути, я хотел бы сохранить значения ячеек в этом столбце даже после вызова DataTable.AcceptChanges, поскольку они не относятся кбазовый источник данных.

Вот пример кода, который воспроизводит то, что я испытываю.Установите флажки в столбце выбора и нажмите Ctrl+S и обратите внимание, что вы будете терять эти проверки каждый раз, даже если они не привязаны к определенному DataGridViewColumn.Я понимаю, что это, вероятно, природа BindingSource, но мне интересно, есть ли способ обойти это поведение.Кроме того, я хотел бы избежать написания логики, которая сохраняет строки, выбранные до вызова AcceptChanges, а затем сбрасывает их после возврата AcceptChanges.Мне это кажется слишком громоздким, если в DataGridView выделено множество строк за один раз.У кого-нибудь есть более хакерская идея?

Public Class Form1
  Sub New()
    InitializeComponent()
    Dim dgv As New DataGridView
    dgv.Columns.Add(New DataGridViewCheckBoxColumn With {.HeaderText = "Selection"})
    dgv.Columns.Add(New DataGridViewTextBoxColumn With {.HeaderText = "ChangeMe", .DataPropertyName = "ChangeMe"})
    Controls.Add(dgv) : dgv.Dock = DockStyle.Fill
    Dim dt = New DataTable : dt.Columns.Add("ChangeMe", GetType(String))
    For Each thing In {"Shoe", "Boat", "Rat"} : dt.Rows.Add(thing) : Next
    dgv.DataSource = New BindingSource(dt, Nothing)
    Me.KeyPreview = True
    AddHandler Me.KeyDown, Sub(sender As Object, e As KeyEventArgs)
                               If e.Control AndAlso e.KeyCode = Keys.S Then dt.AcceptChanges()
                           End Sub
  End Sub
End Class

1 Ответ

0 голосов
/ 22 марта 2019

Проблема вызвана BindingSource повышением события BindingSource.ListChanged типа ListChangedType.Reset в ответ на метод DataTable.AcceptChanges.Когда DataGridView получает это событие, оно перезагружается из BindingSource.. Это происходит в методе ProcessListChanged (прокрутите вниз до строки 658).

Возможным обходным путем является предотвращениеBindingSource от получения событий во время выполнения DataTable.AcceptChanges путем изменения метода обработчика ключа, чтобы он был похож на следующий.

    AddHandler Me.KeyDown, Sub(sender As Object, e As KeyEventArgs)
                                            If e.Control AndAlso e.KeyCode = Keys.S Then
                                                Dim bs As BindingSource = DirectCast(dgv.DataSource, BindingSource)
                                                bs.RaiseListChangedEvents = False
                                                dt.AcceptChanges()
                                                bs.RaiseListChangedEvents = True
                                            End If
                                        End Sub
...