0

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

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

当 Measurements 中的属性足够多时,它会计算 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 方法确实运行正确,并且我最终将另一个测量项添加到 CurrentSample 的测量实体集中。但是,datagridview 不显示新行,并且 MeasurementsBindingSource 只有 1 条记录(但是CurrentSample.Measurements.Count = 2)。

为什么变化CurrentSample.Measurements不传播到MeasurementsBindingSource?我已经尝试过MeasurementsBindingSource.ResetBindings(False), MeasurementsDataGridView.Refresh, SampleDataBindingSource.ResetBindings(False),但似乎没有任何更新MeasurementsBindingSource或其数据网格视图。

4

1 回答 1

0

这是我找到的实体集/绑定源问题的解决方案:

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

这是表单的屏幕截图:

在此处输入图像描述

和代码隐藏:

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 的 Item#3:

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

于 2012-09-05T00:02:14.833 回答