0

I've got two forms. frmProject has an ultragrid of system rows. When I double-click on a row, it opens frmSystem, displaying textboxes populated with details from the active row on frmProject.

I want frmSystem to load the same values as that specified in the ultragridrow on frmProject. I don't want frmSystem to load values from the database table tbl_System. This is because if a user makes changes in frmSystem, those changes are copied back to the dataset behind frmProject (via RaiseEvent RefreshSystemsData) when frmSystem is saved and closed. If the user decides to open frmSystem for the same System row again, populating from the database would show out-of-date values. So I want frmSystem to load its values via copying from the dataset row in frmProject.

In light of this, I added another RaiseEvent to trigger when frmSystem opens. The idea was to read in the System datarow from frmProject.

However, it appears that this RaiseEvent present in each form (referring to each other) is perhaps causing an out of memory exception. The application will not load unless I comment out the code related with PopulateSystemsData and SendSystemDataTofrmSystem.

I would have liked to pass the datarow as a parameter into the InvokeCommand subroutine - but all forms in the database are opened via subroutines in frmMain which contains a whole bunch of other code to do with initialising forms etc etc which I don't want to touch.

I thought about passing the datarow as a series of strings to Options() array in InvokeCommand(), but that would mean all values on frmSystem would be converted to strings, which wouldn't work.

I tried changing the InvokeCommand constructor etc but it started getting really complicated, and I don't want to break the entire application!

I didn't know whether a public function might do it, but I need the datarow to be passed when frmSystem is opened, and it's the frmMain code that handles that.

I need the datarow values at time of InvokeCommand() subroutine execution (done by frmMain).

Any ideas how I can solve this? Here's a cut-down version of the forms code. Thanks in advance for your help.

Public Class frmProject
Private WithEvents frmSystemInst As New frmSystem

Private Sub UGSystem_AfterEnterEditMode(ByVal sender As System.Object, ByVal e As    System.EventArgs) Handles UGSystem.AfterEnterEditMode
            'open System screen for easy editing
'get the active SystemID from ultragrid on frmProject
            Dim intActiveSystemID As Integer = UGSystem.ActiveRow.Cells("SystemID").Value
            Dim intActiveSiteID As Integer = UGSite.ActiveRow.Cells("SiteID").Value
            Dim intSystemID As Integer = 0

            For Each drt As DataRow In DsProjects1.Tables("tbl_System").Rows
                If drt.Item("SystemID") = intActiveSystemID Then
                    Dim i As Integer = drt.Item("RowSaved")
                    If drt.Item("RowSaved") = 1 Then
                        intSystemID = intActiveSystemID
                    End If
                End If
            Next

'This opens frmSystem - executing frmSystem InvokeCommand(...) I would have liked to pass the datarow from frmProject to frmSystem here....
frmMdiParent.openForm("frmSystem", intSystemID & "," &    UGSystem.ActiveRow.Cells("SystemReference").Value & ", " & intActiveSiteID & ", " & intProjectID, -1)

'Get the open frmSystem instance and set it to the instance declared here on frmProject
            For Each f As Form In frmMdiParent.MdiChildren
                If f.Name.Contains("frmSystem") Then
                    frmSystemInst = f
                End If
            Next
        End Sub


Private Sub frmSystemInst_RefreshSystemsData(ByVal d As DataRow) Handles frmSystemInst.RefreshSystemsData
   'JT 9/5/2013: Refresh Systems ultragrid data after the frmSystem is updated and closed

            For Each dr As DataRow In DsProjects1.Tables("tbl_System").Rows
                If dr.Item("SystemID") = d.Item("SystemID") Then
                    For Each dca As DataColumn In dr.Table.Columns
                        For Each dcb As DataColumn In d.Table.Columns
                            If dca.ColumnName = dcb.ColumnName Then
                                dr.Item(dca.ColumnName) = d.Item(dcb.ColumnName)
                            End If
                        Next
                    Next
                End If
            Next

            Me.UGSystem.DataBind()

 'If any System rows exist, mark them as "saved" - this helps distinguish the rows for frmSystem whether the row be already saved to database (correct SystemID), or it's not saved (using a temp SystemID from another row)
            For Each drt As DataRow In Me.DsProjects1.Tables("tbl_System").Rows
                drt.Item("RowSaved") = 1
            Next
        End Sub


Private Sub frmSystemInst_PopulateSystemsData() Handles frmSystemInst.PopulateSystemsData
   'JT 9/5/2013: Send active system datarow from frmProject to frmSystem

        Dim intActiveSystemID As Integer = UGSystem.ActiveRow.Cells("SystemID").Value
        Dim d As DataRow = Nothing

         For Each drt As DataRow In DsProjects1.Tables("tbl_System").Rows
             If drt.Item("SystemID") = intActiveSystemID Then
               d = drt
        End If
        Next

RaiseEvent SendSystemDataTofrmSystem(d)

End Sub

Public Event SendSystemDataTofrmSystem(ByVal d As DataRow)




Public Class frmSystem
Private WithEvents frmProjectInst As New frmProject

Public Sub InvokeCommand(ByVal sender As Object, ByVal e As System.EventArgs, Optional ByVal Options() As String = Nothing) Implements SmartData.MicroGen.IAddIn.IAddIn.InvokeCommand

'get the most recently opened frmProject and set it as the instance from which to get the systems datarow.
For Each f As Form In frmMdiParent.MdiChildren
  If f.Name.Contains("frmProject") Then
     frmProjectInst = f
  End If
Next

'This fires the event on frmProject to get the active system row details.
RaiseEvent PopulateSystemsData()

end sub

'This speaks to frmProject to run the code for updating System ultragrid
Public Event RefreshSystemsData(ByVal d As DataRow)

Private Sub frmProjectInst_SendSystemDataTofrmSystem(ByVal d As DataRow) Handles frmProjectInst.SendSystemDataTofrmSystem
'Copy the System row from frmProject to frmSystem

'Need to add a row to dataset else we'll have nothing to bind to later
Dim rowTemp As DataRow = Me.DsSystemBySystemID1.Tables("get_systems_by_systemID").NewRow
Me.DsSystemBySystemID1.Tables("get_systems_by_systemID").Rows.Add(rowTemp)

  For Each dr As DataRow In DsSystemBySystemID1.Tables("get_systems_by_systemID").Rows
    If dr.Item("SystemID") = d.Item("SystemID") Then
       For Each dca As DataColumn In dr.Table.Columns
         For Each dcb As DataColumn In d.Table.Columns
             If dca.ColumnName = dcb.ColumnName Then
                dr.Item(dca.ColumnName) = d.Item(dcb.ColumnName)
             End If
         Next
       Next
    End If
  Next
End Sub
4

1 回答 1

0

有很多代码需要人们审查!

如果您在其上创建公共方法,frmSystem则可以在打开它后立即使用frmSystemInst并传入数据(数据行?),另外还可以将引用传回调用表单。

然后使用命令按钮或表单关闭事件,frmSystem您可以调用主表单上的方法以使用您传入的引用将数据传回。

于 2013-05-10T17:31:04.853 回答