65.9K
CodeProject 正在变化。 阅读更多。
Home

VB DataGridView 自动将更新保存到绑定的数据库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.53/5 (18投票s)

2006年7月11日

CPOL

2分钟阅读

viewsIcon

213295

downloadIcon

7960

演示如何配置 DataGridView 控件,以自动将绑定数据集的编辑保存到源数据库。

引言

看起来应该很简单。实际上也很简单。但弄清楚如何配置绑定的 DataGridView 控件以自动更新源数据可能是一个挑战。

你是否尝试在 DataGridViewBindingSource 中捕获更新事件并添加更新代码,却只收到一个又一个神秘的错误?如果是这样,那么以下方法可能可以解决你的编程难题。

背景

存储更新的任务似乎并不像一开始看起来那么容易。绑定的 DataGridView 控件似乎在尝试与其自身内部更新同时更新其源时,会变得非常恼火。

一种解决此问题的方法是使用 BindingSourcePositionChanged 事件,如 Peter Huber SG 的 "自动将 DataGridView 行保存到 SQL 数据库" 中所述。但是,PositionChanged 方法可能会留下行删除,尤其是在连续删除多行时。尽管如此,Peter Huber SG 的工作仍然值得研究,特别是他对 DataGridView 内容更改相关事件的跟踪。

延迟更新以避免冲突

PositionChanged 方法从一个正确的想法开始。为了更新绑定的 DataGridView 的底层源,必须在发生更改时记录更改,但必须稍后进行。不幸的是,事件之外的更改过程不一定能记录到每个更改。例如,PositionChanged 不一定会在删除之间触发。

相反,只需使用一个指示器来记录更改的发生情况。

' We need an indicator to know when we need to update the source database
Dim UpdatePending As Boolean = False
Private Sub ExampleBindingSource_ListChanged(ByVal sender As Object, _
        ByVal e As System.ComponentModel.ListChangedEventArgs) _
        Handles ExampleBindingSource.ListChanged
    ' Whenever there is an update, note that a change is pending.
    '
    ' ListChanged does not fire when moving within a row, so this will not
    ' mark updates until done with the row. (Here "done" could mean moving
    ' to another row or closing the form.)
    If Me.ExampleDataSet.HasChanges Then
        Me.UpdatePending = True
        
    End IfEnd
Sub

然后在 BindingSource 完成更改后检查指示器。RowValidated 事件对此非常有效,因为它在 ListChanged 事件之后可靠地触发。

Private Sub DataGridView1_RowValidated(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
        Handles DataGridView1.RowValidated
    ' The RowValidated event occurs after
    ' BindingSource_*Changed operations, which
    ' makes it a good place to update our source database.
    ' However, this event fires at a number
    ' of times when we don't have pending updates.
    ' That's why we need the UpdatePending indicator 
    ' to tell us whether to do anything.
    ' If we have an update pending, copy it to the source database
    If UpdatePending Then
        Me.ExampleTableAdapter.Update(Me.ExampleDataSet.Example)
        Me.UpdatePending = False
    End IfEnd
Sub

关于演示项目

演示项目在其 Form1 中使用了上述解决方案,并包含一个 Visual Studio 2005 项目中的 SQL Express 数据库文件示例。Form2 是 Visual Basic 中 PositionChanged 方法的一个示例。

历史

  • 2006/11/07:原始发布。
© . All rights reserved.