绑定到子实体集的子绑定源不会更新

时间:2012-08-23 21:27:00

标签: .net winforms linq-to-sql bindingsource

我有一个表SampleData,它有一个子表,Measurements。在我的WinForm,frmMain上,一个SampleData对象绑定到SampleDataBindingSource; MeasurementsBindingSource将SampleDataBindingSource作为其数据源,将Measurements作为其DataMember。一组文本框绑定到SampleDataBindingSource; datagridview绑定到MeasurementsBindingSource。

对于frmMain,我还有一个presen类,preMain,它包含一个SampleData类型的属性CurrentSample。 SampleDataBindingSource.DataSource绑定到preMain的CurrentSample属性。

当分配了测量中的足够属性时,它会计算FiringFactor,如果FiringFactor不是1,它会将另一个Measurement项添加到CurrentSample的Measurement实体集中:

Partial Class Measurement

    Private Sub UpdateFiringFactor()
        Dim necessaryDataIsAvailable As Boolean = (Me.CrucibleMass IsNot Nothing And _
                                                   Me.CrucibleSampleFiredMass IsNot Nothing And _
                                                   Me.CrucibleSampleMass IsNot Nothing)
        If necessaryDataIsAvailable Then
            Me.FiringFactor = CDbl((Me.CrucibleSampleFiredMass - Me.CrucibleMass) / (Me.CrucibleSampleMass - Me.CrucibleMass))
            If Me.FiringFactor <> 1 Then
                Me.SampleData.AddNewMeasurement()
            End If
        End If
    End Sub

    Private Sub OnCrucibleMassChanged()
        UpdateFiringFactor()
    End Sub


    Private Sub OnCrucibleSampleFiredMassChanged()
        UpdateFiringFactor()
    End Sub


    Private Sub OnCrucibleSampleMassChanged()
        UpdateFiringFactor()
    End Sub
End Class

当我在datagridview中输入CrucibleMass,CrucibleSampleMass和CrucibleSampleFiredMass的值时,UpdateFiringFactor方法确实正确运行,我最终将另一个Measurement项添加到CurrentSample的Measurements实体集中。但是,datagridview不显示新行,MeasurementsBindingSource只有1条记录(但CurrentSample.Measurements.Count = 2)。

为什么CurrentSample.Measurements中的更改不会传播到MeasurementsBindingSource?我尝试了MeasurementsBindingSource.ResetBindings(False)MeasurementsDataGridView.RefreshSampleDataBindingSource.ResetBindings(False),但似乎没有更新MeasurementsBindingSource或其datagridview。

1 个答案:

答案 0 :(得分:0)

这是我在entityset / bindingsource问题中找到的解决方案:

Imports System.ComponentModel

Partial Class Measurement

    Public Sub ChangeCrucibleMass(ByVal thisMass As Double)
        CrucibleMass = thisMass
        UpdateFiringFactor()
    End Sub

    Public Sub ChangeCrucibleSampleMass(ByVal thisMass As Double)
        CrucibleSampleMass = thisMass
        UpdateFiringFactor()
    End Sub

    Public Sub ChangeCrucibleSampleFiredMass(ByVal thisMass As Double)
        CrucibleSampleFiredMass = thisMass
        UpdateFiringFactor()
    End Sub

    Private Sub UpdateFiringFactor()
        If AllDataAreAvailable() Then
            FiringFactor = (CrucibleSampleFiredMass - CrucibleMass) / (CrucibleSampleMass - CrucibleMass)
            Me.Sample.OnMeasurementsChanged(Nothing, Nothing)
        End If
    End Sub

    Private Function AllDataAreAvailable() As Boolean
        AllDataAreAvailable = False
        Dim allFieldsHaveValue As Boolean = (CrucibleMass IsNot Nothing And CrucibleSampleFiredMass IsNot Nothing And CrucibleSampleMass IsNot Nothing)
        If allFieldsHaveValue Then
            Dim denominatorIsNotZero As Boolean = (CrucibleSampleMass - CrucibleMass) <> 0
            Return denominatorIsNotZero
        End If

    End Function

End Class

Partial Class Sample

    Public Sub OnMeasurementsChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Handles Me.PropertyChanged
        If Me.Measurements.Count > 0 AndAlso Me.Measurements.Last.FiringFactor IsNot Nothing AndAlso Me.Measurements.Last.FiringFactor <> 1 Then
            Me.Measurements.Add(New Measurement With {.CrucibleMass = Me.Measurements.Last.CrucibleMass})
            RaiseEvent RefreshMeasurementsBinding()
        End If
    End Sub

    Private Sub OnCreated()
        Me.Measurements.Add(New Measurement)
    End Sub

    Public Event RefreshMeasurementsBinding()

End Class

以下是表单的截图:

enter image description here

代码隐藏:

Imports System.ComponentModel

Public Class Form1

    Private WithEvents newSample As Sample

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        newSample = SampleConduit.GetSample(1)
        'newSample = New Sample
        Me.SampleBindingSource.DataSource = newSample
        OnRefreshMeasurementsBinding()

    End Sub

    Private Sub OnRefreshMeasurementsBinding() Handles newSample.RefreshMeasurementsBinding
        Me.MeasurementsBindingSource.DataSource = newSample.Measurements.GetNewBindingList
    End Sub


    Private Sub MeasurmentsDataGridView_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles MeasurmentsDataGridView.CellClick
        Me.MeasurementsBindingSource.EndEdit()
        Dim currentMeasurement = CType(Me.MeasurementsBindingSource.Current, Measurement)
        Select Case e.ColumnIndex
            Case 0
                currentMeasurement.ChangeCrucibleMass(GetMeasurement)
            Case 1
                currentMeasurement.ChangeCrucibleSampleMass(GetMeasurement)
            Case 2
                currentMeasurement.ChangeCrucibleSampleFiredMass(GetMeasurement)
        End Select
    End Sub

    Private Function GetMeasurement() As Double
        Return CDbl(InputBox("Measurement:", "Get Measurement", "0"))
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        Dim currentSample = CType(Me.SampleBindingSource.Current, Sample)
        SampleConduit.SaveSample(currentSample)
    End Sub
End Class

解决方案取决于Sample类中的RefreshMeasurementsBinding事件和表单中的OnRefreshMeasurementsBinding方法。经常将MeasurementsBindingSource设置为Measurements实体集上的GetNewBindingList方法似乎有些麻烦,但它可以工作。

在此论坛帖子中查看关于EntitySets和BindingSource以及GetNewBindingList的第3项:

http://www.infragistics.com/community/forums/t/43526.aspx