Dataset global im Programm verfügbar machen

  • VB.NET
  • .NET (FX) 4.0

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Dataset global im Programm verfügbar machen

    Hallo Leute,

    Also folgendes Problem:

    Im Main habe ich:

    VB.NET-Quellcode

    1. Private Sub AddMdiChild(Of T As {Form, New})(ByVal dataset As DataSet)
    2. Dim NewWindow = Dataset.CreateForm(Of T)()
    3. NewWindow.MdiParent = Me
    4. NewWindow.Show()
    5. End Sub



    Und für jedes zu öffnende Form:

    VB.NET-Quellcode

    1. Private Sub ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SurfaceToolStripMenuItem.Click
    2. Select Case True
    3. Case sender Is SurfaceToolStripMenuItem
    4. AddMdiChild(Of fmSurface)(Program.DS)



    Und das dazugeörige Modul:

    VB.NET-Quellcode

    1. Public Module Program
    2. Public ReadOnly DS As New AMSDataSet
    3. <STAThread()> _
    4. Public Sub Main(ByVal commandLineArgs As String())
    5. Application.EnableVisualStyles()
    6. Application.SetCompatibleTextRenderingDefault(False)
    7. Dim Adp = New DatasetAdapter(SqlClient.SqlClientFactory.Instance, My.Settings.AMSConnectionString, ConflictOption.OverwriteChanges)
    8. DS.Adapter(Adp).Register(fmMain)
    9. Application.Run(DS.CreateForm(Of fmMain))
    10. My.Settings.Save()
    11. End Sub



    Aber das ganze funzt nicht. In meiner Form ist das Dataset immer nothing.

    Hoffe ihr könnt mir helfen.

    Vielleicht noch erwähnenswert dass ich mit den 2010er DB-Extensions von Erfinder des Rades arbeite.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „TS71M“ ()

    und in den DBExtensions gibts eine Methode Dataset.CreateForm()?

    Ich würd halt vorschlagen, du benutzt die Dataset.Register() - Methode, wie in der dortigen Sample-Solution mehrfach gezeigt:
    Registrieren kann ein Form erst dann sein Dataset, wenn seine InitializeComponents-Methode durchgelaufen ist.

    Das ist bei deinem Zugriff in Sub Main vermutlich nicht der Fall.
    Ja, allerdings habe ich diese dazukopiert.

    VB.NET-Quellcode

    1. <Extension()> _
    2. Public Function CreateForm(Of T As {Form, New})(ByVal Subj As DataSet) As T
    3. CreateForm = New T
    4. Call New FormDataSourceReplacer(Subj).RecurseControls(CreateForm)
    5. End Function
    6. Private Class FormDataSourceReplacer
    7. Dim _Dts As DataSet
    8. Dim tp As Type
    9. Private Function shouldReplace(ByVal src As Object) As Boolean
    10. Return src IsNot Nothing AndAlso src Is tp OrElse src.GetType Is tp AndAlso src IsNot _Dts
    11. End Function
    12. Dim bindFlags As BindingFlags = BindingFlags.Instance Or BindingFlags.Public _
    13. Or BindingFlags.NonPublic Or BindingFlags.GetField
    14. Public Sub New(ByVal Subj As DataSet)
    15. tp = Subj.GetType
    16. _Dts = Subj
    17. Dim recursive As Action(Of Control) = Nothing
    18. End Sub
    19. Public Sub RecurseControls(ByVal ctl As Control)
    20. For Each fld In ctl.GetType.GetFields(bindFlags)
    21. If fld.FieldType Is tp Then
    22. fld.SetValue(ctl, _Dts)
    23. Continue For
    24. End If
    25. If Not GetType(IComponent).IsAssignableFrom(fld.FieldType) Then Continue For
    26. With fld.FieldType.GetProperty("DataSource")
    27. If .Null Then Continue For
    28. Dim itm = fld.GetValue(ctl)
    29. If itm Is Nothing Then Continue For
    30. Dim bs = TryCast(itm, BindingSource)
    31. If bs.NotNull Then System.Windows.Forms.DataTable(bs).Events.AddSource(bs)
    32. If shouldReplace(.GetValue(itm, Nothing)) Then .SetValue(itm, _Dts, Nothing)
    33. End With
    34. Next
    35. ctl.Controls.OfType(Of Control).ForEach(AddressOf RecurseControls)
    36. End Sub
    37. End Class


    War das nicht so schlau?