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