У меня две формы. frmProject имеет ультрасетку системных строк. Когда я дважды щелкаю строку, она открывает frmSystem, отображая текстовые поля, заполненные сведениями из активной строки в frmProject.
Я хочу, чтобы frmSystem загрузила те же значения, которые указаны в ультрагриде на frmProject. Я не хочу, чтобы frmSystem загружала значения из таблицы базы данных tbl_System. Это связано с тем, что если пользователь вносит изменения в frmSystem, эти изменения копируются обратно в набор данных позади frmProject (через RaiseEvent RefreshSystemsData) при сохранении и закрытии frmSystem. Если пользователь решит снова открыть frmSystem для той же строки System, заполнение из базы данных покажет устаревшие значения. Итак, я хочу, чтобы frmSystem загружала свои значения путем копирования из строки набора данных в frmProject.
В свете этого я добавил еще одно событие RaiseEvent, которое будет срабатывать при открытии frmSystem. Идея заключалась в том, чтобы прочитать строку данных System из frmProject.
Однако похоже, что это событие RaiseEvent, присутствующее в каждой форме (ссылающееся друг на друга), возможно, вызывает исключение нехватки памяти. Приложение не загрузится, пока я не закомментирую код, связанный с PopulateSystemsData и SendSystemDataTofrmSystem.
Мне бы хотелось передать строку данных в качестве параметра в подпрограмму InvokeCommand, но все формы в базе данных открываются с помощью подпрограмм в frmMain, который содержит целую кучу другого кода, связанного с инициализацией форм и т. д. и т. д., который я не хочу трогать.
Я думал о передаче строки данных в виде серии строк в массив Options() в InvokeCommand(), но это означало бы, что все значения в frmSystem будут преобразованы в строки, что не сработает.
Я попытался изменить конструктор InvokeCommand и т. д., но он стал очень сложным, и я не хочу ломать все приложение!
Я не знал, может ли это сделать общедоступная функция, но мне нужно, чтобы строка данных передавалась при открытии frmSystem, и это обрабатывает код frmMain.
Мне нужны значения строки данных во время выполнения подпрограммы InvokeCommand() (выполняется frmMain).
Любые идеи, как я могу это решить? Вот урезанная версия кода формы. Заранее спасибо за помощь.
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