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