如何向绑定源添加新行



我正在尝试以编程方式向绑定源添加新行。我知道调用bsSource.AddNew()添加了一个新行,我将其转换为DataRowView并设置我的值。我的问题是这个- DataRowView。Row显示的RowState为detached。我不希望它被分离;我相信它应该显示添加-我也不希望它提交更改到数据库(这是一个非常有效的理由)。我想以后再找时间。我的代码如下:

private Sub AddToRelationSource(binID As Integer, gradeID As Integer, IsChecked As Boolean)
            Dim drv As DataRowView = DirectCast(bsBinGrades.AddNew(), DataRowView)

            drv.Row("IsSelected") = IsChecked
            drv.Row("BinID") = binID
            drv.Row("GradeID") = gradeID
    ' I tried drv.EmdEdit(0 drv.Row.EndEdit() - Row State still shows detached
End Sub

BindingSource AddNew方法实际上并不向底层数据源添加新记录,它只是将其作为分离项添加到BindingSource中。当使用数据标签作为数据源时,我需要获取数据表并使用AddRow()方法-这将正确地将我的bindingsource中的值设置为added,以便当更改将通过bindingsource. update()方法提交到数据库时。

我使用的代码:

    Dim drv As DataRowView = DirectCast(bsData.AddNew(), DataRowView)
    drv.BeginEdit()
    drv.Row.BeginEdit()
    drv.Row("IsSelected") = IsChecked
    drv.Row.EndEdit()
    drv.DataView.Table.Rows.Add(drv.Row)

最后一行是实际将项目添加到数据源的内容——我误解了BindingSource.AddNew()。

以下可能是正确的方向。首先,我使用了一些语言扩展方法,例如

Public Module BindingSourceExtensions
    <Runtime.CompilerServices.Extension()>
    Public Function DataTable(ByVal sender As BindingSource) As DataTable
        Return CType(sender.DataSource, DataTable)
    End Function
    <Runtime.CompilerServices.Extension()>
    Public Sub AddCustomer(ByVal sender As BindingSource, ByVal FirstName As String, ByVal LastName As String)
        sender.DataTable.Rows.Add(New Object() {Nothing, FirstName, LastName})
    End Sub
    <Runtime.CompilerServices.Extension()>
    Public Function DetachedTable(ByVal sender As BindingSource) As DataTable
        Return CType(sender.DataSource, DataTable).GetChanges(DataRowState.Detached)
    End Function
    <Runtime.CompilerServices.Extension()>
    Public Function AddedTable(ByVal sender As BindingSource) As DataTable
        Return CType(sender.DataSource, DataTable).GetChanges(DataRowState.Added)
    End Function
End Module

现在将ID, FirstName和LastName加载到DataTable中,DataTable成为BindingSource的数据源,BindingSource是BindingNavigator的BindingSource,并连接到DataGridView。

为了保持简单,我模拟了数据,没有断言,例如确保我们有有效的姓和名,而不是集中在方法上。

首先使用扩展方法向BindingSource的底层数据表添加一行。

bsCustomers.AddCustomer("Karen", "Payne")

现在检查是否有分离或添加的行

Dim detachedTable As DataTable = bsCustomers.DetachedTable
If detachedTable IsNot Nothing Then
    Console.WriteLine("Has detached")
Else
    Console.WriteLine("No detached")
End If
Dim AddedTable As DataTable = bsCustomers.AddedTable
If AddedTable IsNot Nothing Then
    Console.WriteLine("Has added")
Else
    Console.WriteLine("None added")
End If

由于我们没有与数据库表通信,主键没有按预期更新,并且由于您不想更新数据库表,这是可以的。当然,如果您在项目后期需要,有一种方法可以获取新添加记录的主键。

添加

Private Sub BindingSource1_AddingNew(ByVal sender As System.Object, ByVal e As System.ComponentModel.AddingNewEventArgs) Handles BindingSource1.AddingNew
  Dim drv As DataRowView = DirectCast(BindingSource1.List, DataView).AddNew()
  drv.Row.Item(0) = "some value"
  e.NewObject = drv
  ' move to new record
  'BindingSource1.MoveLast()
End Sub

'这个例程使用AddForm,其中包含用户需要的各种字段'填充并调用TableAdapter的Insert方法。在这之后,桌子就会被反射回来各种组件。

Private Sub AddRecord()
    'The following line did not work because I could not get
    'the bs definition down.
    'Tried the BindingSource but in gave an error on 
    'DataRowView so I came up with an alternate way of 
    'adding the row.
    'Dim drv As DataRowView = DirectCast(bsData.AddNew(), DataRowView)
    'Dim drv As DataRowView = DirectCast(RecTableBindingSource.AddNew(), DataRowView)
    'drv.BeginEdit()
    'drv.Row.BeginEdit()
    'drv.Row("Title") = "Order, The"
    'drv.Row.EndEdit()
    'drv.DataView.Table.Rows.Add(drv.Row)
    RecTableTableAdapter.Insert(pAddForm.tTitle.Text,
                                pAddForm.tCast.Text,
                                pAddForm.tAKA.Text,
                                pAddForm.tRelated.Text,
                                pAddForm.tGenre.Text,
                                pAddForm.tRated.Text,
                                pAddForm.tRelease.Text,
                                pAddForm.tLength.Text)
    Validate()
    RecTableBindingSource.EndEdit()
    RecTableTableAdapter.Update(VideoDBDataSet.RecTable)
    RecTableAdapterManager.UpdateAll(VideoDBDataSet)
    RecTableTableAdapter.Fill(VideoDBDataSet.RecTable)
    VideoDBDataSet.AcceptChanges()
End Sub
'Here is my Delete Record routine
Private Sub DeleteRecordToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DeleteRecordToolStripMenuItem.Click
    Dim RowIndex As Int32
    If (dgvRec.SelectedRows.Count > 0) Then
        RowIndex = dgvRec.SelectedRows(0).Index
        'Now we have to delete the record
        dgvRec.Rows.RemoveAt(RowIndex)
        dgvRec.CommitEdit(RowIndex)
        dgvRec.EndEdit()
        Validate()
        RecTableBindingSource.EndEdit()
        RecTableTableAdapter.Update(VideoDBDataSet.RecTable)
        RecTableAdapterManager.UpdateAll(VideoDBDataSet)
        RecTableTableAdapter.Fill(VideoDBDataSet.RecTable)
        VideoDBDataSet.AcceptChanges()
    Else
        'No row selected to work with
    End If
End Sub
'The pAddForm MUST be open for this routine to work
Private Sub UpdateGridFromForm()
    Dim RowIndex As Int32
    Dim Index As Int32
    Dim RecIndex As Int32
    Dim dt As DataTable
    If ((pAddForm Is Nothing) = False) Then
        RowIndex = pAddForm.GridIndex
        If (RowIndex >= 0) Then
            Index = pAddForm.Index
            If (Index = dgvRec.Rows(RowIndex).Cells(constRecGridColIndex).Value) Then
                'OK, we have a match so we are good to go
                Call PopulateGridFields(RowIndex)
            Else
                MsgBox("Unable to save data back to the Grid because the record is no longer the same")
            End If
        Else
            'This must be a NEW record
            Call AddRecord()
        End If
    Else
        'No form to work with
    End If
End Sub
'Populate the dgvRec fields from pAddForm
Private Sub PopulateGridFields(RowIndex As Int32)
    dgvRec.Rows(RowIndex).Cells(constRecGridTitle).Value = pAddForm.tTitle.Text
    dgvRec.Rows(RowIndex).Cells(constRecGridCast).Value = pAddForm.tCast.Text
    dgvRec.Rows(RowIndex).Cells(constRecGridAKA).Value = pAddForm.tAKA.Text
    dgvRec.Rows(RowIndex).Cells(constRecGridRelated).Value = pAddForm.tRelated.Text
    dgvRec.Rows(RowIndex).Cells(constRecGridGenre).Value = pAddForm.tGenre.Text
    dgvRec.Rows(RowIndex).Cells(constRecGridRated).Value = pAddForm.tRated.Text
    dgvRec.Rows(RowIndex).Cells(constRecGridRelease).Value = pAddForm.tRelease.Text
    dgvRec.Rows(RowIndex).Cells(constRecGridLength).Value = pAddForm.tLength.Text
    dgvRec.CommitEdit(RowIndex)
    dgvRec.EndEdit()
    Validate()
    RecTableBindingSource.EndEdit()
    RecTableTableAdapter.Update(VideoDBDataSet.RecTable)
    RecTableAdapterManager.UpdateAll(VideoDBDataSet)
    RecTableTableAdapter.Fill(VideoDBDataSet.RecTable)
    VideoDBDataSet.AcceptChanges()
End Sub

'这一切都很好。
我现在唯一的问题是DataGridView会总是重新填充网格(包括任何更改与"添加/删除/修改"发送活动'row back to the top of grid

'我将工作的解决方案,现在我有剩下的工作

相关内容

  • 没有找到相关文章

最新更新