передать строку данных из другой формы, используя несколько RaiseEvents

У меня две формы. 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

person No1fan    schedule 10.05.2013    source источник


Ответы (1)


Это очень много кода, который люди должны просмотреть!

Если вы создаете общедоступный метод для frmSystem, вы можете вызвать его с помощью frmSystemInst и передать данные сразу после его открытия (datarow?), а также передать ссылку обратно в вызывающую форму.

Затем, используя командную кнопку или событие закрытия формы в frmSystem, вы можете вызвать метод в основной форме для передачи данных обратно, используя переданную вами ссылку.

person PatFromCanada    schedule 10.05.2013