Zugriff auf Properties eine UserControls

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von roepke.

    Zugriff auf Properties eine UserControls

    Ich seh wohl vor lauter Bäumen den Wald nicht mehr.
    Im angehängten Beispiel wird per "Add Tab Page" eine neue TabPage in einem TabControl hinzugefügt und darauf ein UserControl platziert.
    In diesem UserControl, auf der neuen TabPage soll nun vom gleichen UserControl auf der TabPage davor eine Property abgefragt werden.
    (GetXnFromPreviousCurvePart())
    Ich kann es drehen und wenden wie ich will, ich kann nicht darauf zugreifen.
    Bestimmt ganz simpel, ich stehe gerade auf dem Schlauch.
    Wäre dankbar für den entscheidenen Hinweis.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roepke“ ()

    @roepke So was, übergib den SelectedIndex als Parameter im Konstruktor:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class FGEditor
    2. 'LoadThisForm_Load():
    3. Private Sub LoadThisForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    4. Add_UserControl_ToTabPage(TabControl.TabPages(0), 0)
    5. End Sub
    6. 'btn_AddTabPage_Click(): ermöglicht eine neue TabPage HINTER der aktuell selektierten TabPage im TabControl hinzuzufügen
    7. Private Sub btn_AddTabPage_Click(sender As Object, e As EventArgs) Handles btn_AddTabPage.Click
    8. Dim _i As Integer = TabControl.SelectedIndex
    9. Dim _tp As New TabPage
    10. _tp.Text = "TabPage" & (TabControl.TabPages.Count + 1)
    11. _tp.Name = "TabPage" & (TabControl.TabPages.Count + 1)
    12. TabControl.TabPages.Insert(_i + 1, _tp)
    13. Add_UserControl_ToTabPage(_tp, _i + 1)
    14. End Sub
    15. 'Add_UserControl_ToTabPage(): platziert ein uc_FGEditor auf der neuen TabPage
    16. Private Sub Add_UserControl_ToTabPage(tp As TabPage, index As Integer)
    17. Dim _uc As New uc_FGEditor(index)
    18. _uc.Name = "uc_FGEditor_" & tp.Name
    19. tp.Controls.Add(_uc)
    20. End Sub
    21. End Class

    VB.NET-Quellcode

    1. Public Class uc_FGEditor
    2. Dim dCurrentXn As Double = 0
    3. Dim dCurrentYn As Double = 0
    4. Private Index As Integer
    5. Public Sub New(ind As Integer)
    6. Me.Index = ind
    7. InitializeComponent()
    8. End Sub
    9. Friend Property pdCurrentXn As Double
    10. Get
    11. pdCurrentXn = dCurrentXn
    12. End Get
    13. Set(ByVal dValue As Double)
    14. dCurrentXn = dValue
    15. lbl_CurrentXnFromPreviousCurvePart_Result.Text = dValue.ToString
    16. End Set
    17. End Property
    18. Friend Property pdCurrentYn As Double
    19. Get
    20. pdCurrentYn = dCurrentYn
    21. End Get
    22. Set(ByVal dValue As Double)
    23. dCurrentYn = dValue
    24. lbl_CurrentYnFromPreviousCurvePart_Result.Text = dValue.ToString
    25. End Set
    26. End Property
    27. 'LoadThisUserControl_Load(): UserControl .Load wird erst ausgeführt, wenn der zugehörige Tab erstmalig geöffent und angezeigt wird.
    28. Private Sub LoadThisUserControl_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
    29. GetXnFromPreviousCurvePart()
    30. End Sub
    31. Private Sub GetXnFromPreviousCurvePart()
    32. Dim _tp As TabPage = CType(Parent, TabPage)
    33. Dim _tc As TabControl = CType(_tp.Parent, TabControl)
    34. Dim _i As Integer = Me.Index '_tc.SelectedIndex
    35. lbl_MyTabIndex_Result.Text = _i.ToString
    36. If _i > 0 Then
    37. Dim tpx As TabPage = _tc.TabPages(_i - 1)
    38. For Each ctrl As Control In tpx.Controls
    39. If TypeOf ctrl Is uc_FGEditor Then
    40. 'Dim d As Double = ctrl.pdCurrentXn
    41. Dim i As Integer = 0
    42. End If
    43. Next
    44. For Each uc As UserControl In tpx.Controls.OfType(Of UserControl)()
    45. 'Dim d As Double = uc.pdCurrentXn
    46. 'Wieso kann ich hier nicht auf die Properies des UserControls zugreifen?
    47. Next
    48. End If
    49. End Sub
    50. End Class
    Wenn Du weitere Properties brauchst, lege sie in der TabPage und / oder im UserControl an und befülle sie im Hauptprogramm.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    Danke an @RodFromGermany, das löst aber leider nicht mein Problem welches ich in diesem Thread versuche zu lösen.
    Du hast da vermutlich mit meinem anderen Thema von heute früh was zusammengebracht, was nicht ganz zusammen gehört.
    In beiden Fällen geht es zwar um ein UserControl, aber die Aufgabe ist unterschiedlich.
    Konkret:
    Ich habe ein TabControl dem ich zur Laufzeit beliebig TabPages hinzufügen kann (btn_AddTabPage_Click in Public Class FGEditor).
    Auf jeder TabPage wird dabei ein UserControl angelegt (Add_UserControl_ToTabPage in Public Class FGEditor).
    Das UserControl uc_FGEditorbesitzt die Public/Friend Properties Public Property pdCurrentXn As Double und Public Property pdCurrentYn As Double.
    Das Hauptprogramm kann auch problemlos auf diese Properties zugreifen und sie füllen und lesen
    Wird eine neue TapPage mit einem neuen UserControl hinzugefügt, soll das neue UserControl auf der TabPage in der Lage sein die Properties Public Property pdCurrentXn As Double und Public Property pdCurrentYn As Double des UserControls auf der TabPage.Index -1 zu lesen. Dies passiert im angehängten Beispiel im Moment des ersten Aufrufs des UserControls. Es soll aber auch jeder Zeit durch drücken eines Button auf dem UserControl möglich sein, evtl. auf der TabPage.Index-1 vom Hauptprogramm geänderte Properties erneut zu lesen.
    Wohl gemerkt: das Hauptprogramm füttert die Propertys des UserControls, aber das UserControl selbst soll die Properties der Instanz auf der vorherigen TabPage lesen können.
    Ich habe das angehängte Beispiel dahingehend noch um einen Button im UserControl ergänzt.
    Das UserControl greift für diesen Property-Lesevorgang über seine Parent TabPage auf deren Parent TabControl zu, erstellt von der TabPage-1 eine Kopie, durchsucht diese Kopie nach UserControls vom eigenen Typ und will die Properties lesen.
    Und da scheitert es dann, da in tpx (Zeile 43 von uc_FGEditor) eine Kopie der richtigen TabPage zu sein schein, in Zeile 45 das ctrl gefunden wird, aber nachfolgend die Properties pdCurrentXn und pdCurrentYn keine Mitglieder von ctrl sind.
    Vermutlich weise ich falsch zu oder übersehe einen Cast oder sonst was.
    Dateien
    @roepke OK, dann war das ein Missverständnis.
    Zwei Tabs eines TabControls und deren (User-)Controls sollten eigentlich nichts voneinander wissen.
    Mach es ggf. so:
    Das Hauptfenster bzw. das TabControl wissen, welche TabPage als vorletztes und als letztes hinzugefügt wurden.
    An dieser Stelle sollte die Information übertragen werden, das geht dann in beide Richtungen.
    Wenn Du Dir eine Liste von Deinen { Controls mit dem jeweiligen Vorgänger und Nachfolger } anlegst, kannst Du Dich dort durch-iterieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Im Grunde wissen sie ja auch nix direkt voneinander, vielmehr soll das eine UserControl ja das andere auf der vorherigen TabPage suchen und wenn es das findet die Infos dort 'rausquetschen'.
    Habe mir aber gerade überlegt, dass ich das Ganze ja im Grunde auch per Event lösen könnte. Das UserControl feuert ein Event, auf dass das ParentForm reagiert und die Infos an alle verfügbaren TabPages mit allen darauf vorhandenen UserControls neu verteilt.
    Das Problem ist nämlich so gelagert, dass die TabPages auch noch nach belieben verschoben, wieder entfernt oder mittendrin neue hinzugefügt werden können. Dadurch würden sich diese Infos der Properties jedes Mal ohnehin völlig neu verteilen. Da ist vermutlich die Sache mit dem Event nicht schlecht, zumal das ParentForm beim ändern der TabPages ohnehin die Infos quasi ggf. in jedem UserControl aktualisieren muss.
    @roepke Oder so.
    Vielleicht skizzierst Du mal, welche Informationen von wo nach wo fließen.
    Ohne VB-Code.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    roepke schrieb:

    Habe mir aber gerade überlegt, dass ich das Ganze ja im Grunde auch per Event lösen könnte. Das UserControl feuert ein Event, auf dass das ParentForm reagiert und die Infos an alle verfügbaren TabPages mit allen darauf vorhandenen UserControls neu verteilt.
    Jo, das ist grundsätzlich die richtige Architektur, wenn ein ucl mit einem anderen telefonieren muss, und weder ucl1 ist in ucl2, noch ucl2 ist in ucl1.
    Noch besser aber wäre, ucl1 müsste garnet mit ucl2 telefonieren.
    Etwa - wenn es um Daten geht - mit einem globalen Datenmodell hat man nochma ganz andere Möglichkeiten.

    Das Form besitzt ein TabControl.
    Das TabControl besitzt eine beliebige Anzahl TabPages, die der Anwender einfügen/entfernen/verschieben kann.
    Je TabPage besitzt ein UserControl.
    Jedes UserControl kann vom Anwender mit Parametern gefüllt werden und führt damit Berechnungen durch.
    Die Berechnung selbst startet der Anwender über einen Button im Form.
    Das Ergebnis der Berechnung wird mittels Event als Tabellendaten an das Form übergeben und dort sequenziell in eine Tabelle eingetragen, die die Ergebnisse aller UserControls zusammenfasst.
    Jedes UserControl führt seine Berechnung nach dem vorherigen UserControl durch, da es als Startwerte die Endwerte des vorherigen UserControls benötigt.
    Diese Werte übergibt das Form an das nachfolgende UserControl, sobald es die Daten des vorherigen erhalten hat und startet damit die Berechnung des nachfolgenden UserControl.
    Was ganz nett wäre, wenn das nachfolgende UserControl die Parameter des vorherigen UserControl bei Bedarf übernehmen könnte.
    Daher der Versuch mittels:

    VB.NET-Quellcode

    1. Private Sub GetXnFromPreviousCurvePart()
    2. Dim _tp As TabPage = CType(Parent, TabPage)
    3. Dim _tc As TabControl = CType(_tp.Parent, TabControl)
    4. Dim _i As Integer = _tc.SelectedIndex
    5. lbl_MyTabIndex_Result.Text = _i.ToString
    6. If _i > 0 Then
    7. Dim _tpx As TabPage = _tc.TabPages(_i - 1)
    8. For Each _ctrl As Control In _tpx.Controls
    9. If TypeOf _ctrl Is uc_FGEditor Then
    10. 'Dim _d As Double = _ctrl.pdCurrentXn
    11. 'Wieso kann ich hier nicht auf die Properies des UserControls zugreifen?
    12. End If
    13. Next
    14. End If
    15. End Sub

    auf das vorherige UserControl direkt zugreifen zu können und dessen PublicProperties zu lesen.
    Vermutlich wäre ja auch hier die saubere Lösung, das mittels Event aus dem UserControl heraus das Form erledigen zu lassen, welches problemlos auf die Properties der UserControls zugreifen kann,
    Warum komme ich aber seitens des UserControl selbst nicht an das vorherige ran?
    Weil Dir die Compilerfehlermeldung sagt, dass pdCurrentXn kein Bestandteil von CONTROL ist. Caste also vorher _ctrl nach uc_FGEditor und dann geht's.
    Oder anders:

    VB.NET-Quellcode

    1. If _i > 0 Then
    2. Dim _tpx As TabPage = _tc.TabPages(_i - 1)
    3. For Each _ctrl In _tpx.Controls.OfType(Of uc_FGEditor)
    4. Dim _d As Double = _ctrl.pdCurrentXn
    5. Next
    6. End If
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @roepke Da bin ich wieder bei meiner List(Of uc_FGEditor).
    Ich gehe mal davon aus, dass die Controls in der richtigen Reihenfolge erstellt werden.
    Wenn Du sie parallel dazu in einer List(Of uc_FGEditor) ablegst, musst Du die betreffenden Prozeduren nur noch in einer For-Schleife aufrufen.
    Wenn die Controls wissen, ob sie Parameter vom Vorgänger brauchen, gib ihnen den Vorgänger mit.
    Feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!