UserControl-Elemente mit Form kompatibel machen

  • VB.NET
  • .NET 5–6

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    UserControl-Elemente mit Form kompatibel machen

    Hallo,

    wenn mein Form ein Private feld as ExampleClass hat, dann kann ich in einem Button-Click Event feld verwenden.
    Das klappt bei einem UserControl nicht, da ein Button dann ja zum UC gehört und nicht zu dem Form auf dem es später sitzt.

    Kann man das irgendwie einbauen, das Buttons vom UC auch das Form kennen auf dem das UC platziert wird?

    Achso das feld auf Friend setzten und per Form.feld addressieren ist mir klar funktioniert, aber das ist nicht die gleiche Funktionalität wie bei einem Button der zum Form gehört, oder?

    Viele Grüße

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

    @Haudruferzappeltnoch Das ist nicht die Idee von UserControls.
    Die UserControl-Button-Click kann ein Event an die Parent-Form senden.
    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!
    jou.
    Also die ParentForm kann mit AddHandler das Click-Event des Buttons abonnieren, der auf dem UserControl aufsitzt.
    Weil die ParentForm kennt ja das UserControl - andersrum müssste man ein bischen was frickeliges frickeln.

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

    Das UC und somit der Button auf dem UC kennen das Form. Im Button-Click-EventHandler könnte also stehen:

    VB.NET-Quellcode

    1. Me.ParentForm.BackColor = Drawing.Color.Red

    Aber was soll das werden, wenn's fertig ist? Es ist normalerweise keine gute Idee, wenn das SubControl den eigenen Container kennt.
    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.
    Ok, dann hab ich es nicht ganz verstanden.

    Ich hatte ursprünglich so eine Methode:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Aktualisieren
    3. Bereich1Kram()
    4. Bereich2Kram()
    5. Bereich3Kram()
    6. End Sub
    7. ' Dazu hier noch die ganzen Events (mehrere Dinge aus jedem Bereich)
    8. End Class

    Ich dachte ein UserControl bietet sich an um das ganze besser zu strukturieren. Jede Bereich macht seinen eigenen Teil

    VB.NET-Quellcode

    1. Friend Class UserControl1
    2. Private Sub Aktualisieren
    3. Bereich1Kram()
    4. End Sub
    5. 'Die Events zu UC1
    6. End Class
    7. Friend Class UserControl2
    8. Private Sub Aktualisieren
    9. Bereich2Kram()
    10. End Sub
    11. 'Die Events zu UC2
    12. End Class
    13. Friend Class UserControl3
    14. Private Sub Aktualisieren
    15. Bereich3Kram()
    16. End Sub
    17. 'Die Events zu UC3
    18. End Class

    Die Methoden in Aktualisieren benötigen das feld, damit ists dann nicht mehr sinnvoll?

    Wenn ich mit dem ParentForm die Events abonniere, dann bin ich ja wieder mit allem auf einem Haufen. Dann kann ich mir die UCs ja sparen.

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

    @Haudruferzappeltnoch Gib den UserContrrols entweder eine gemeinsame Basisklasse oder ein Interface.
    Dann kannst Du das ganze elegant über eine List(Of BaseUserControl) oder List(Of IUserControl) abwickeln.
    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!

    Haudruferzappeltnoch schrieb:

    Ich dachte ein UserControl bietet sich an um das ganze besser zu strukturieren. Jede Bereich macht seinen eigenen Teil

    ja, ist doch richtig. Aber sso:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Aktualisieren
    3. ucl1.Aktualisieren()
    4. ucl2.Aktualisieren()
    5. ucl3.Aktualisieren()
    6. End Sub
    also jedes ucl hat seine eigene Aktualisieren()-Methode
    Wenn es nur um 3 UCs geht, kannst Du denen jeweils auch ne Methode SetData geben:

    VB.NET-Quellcode

    1. Friend Class UserControl1
    2. Private feld as ExampleClass
    3. Friend Sub SetData(feld As ExampleClass)
    4. Me.feld = Feld
    5. End Sub
    6. Private Sub Aktualisieren
    7. Bereich1Kram()
    8. End Sub
    9. 'Die Events zu UC1
    10. End Class
    11. Friend Class UserControl2
    12. Private feld as ExampleClass
    13. Friend Sub SetData(feld As ExampleClass)
    14. Me.feld = Feld
    15. End Sub
    16. Private Sub Aktualisieren
    17. Bereich2Kram()
    18. End Sub
    19. 'Die Events zu UC2
    20. End Class
    21. Friend Class UserControl3
    22. Private feld as ExampleClass
    23. Friend Sub SetData(feld As ExampleClass)
    24. Me.feld = Feld
    25. End Sub
    26. Private Sub Aktualisieren
    27. Bereich3Kram()
    28. End Sub
    29. 'Die Events zu UC3
    30. End Class

    Und dann im Form aufrufen:

    VB.NET-Quellcode

    1. UC1.SetData(Me.feld)
    2. UC2.SetData(Me.feld)
    3. UC3.SetData(Me.feld)

    Dann können die UCs auch was damit machen und Du musst nicht mit Vererbung arbeiten, falls Du das nicht willst.
    Je mehr UCs es werden, die auf feld zugreifen müssen, desto mehr lohnt sich die Vererbung.
    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.
    Und wenn das UserControl etwas an sein Parent (die Form in der es lebt) schicken soll, dann kann man das im UserControl mit einem RaiseEvent machen.
    Ins Usercontrol käme dann :

    VB.NET-Quellcode

    1. Public Event MeinNeuerEventname(ByVal sender As Object, ByVal e As EventArgs)

    Und das Usercontrol kann dann mit

    VB.NET-Quellcode

    1. Dim e = New EventArgs
    2. RaiseEvent MeinNeuerEventname(Me, e)

    im Parent sich selbst bemerkbar machen und etwas auslösen.
    Wobei du über EventArgs deinem Parent noch Daten geben kannst, dass dein Parent dann die in ihm aufgerufenen Events auseinanderhalten und verarbeiten kann.
    Falls sowas doch mal begraucht wird, habe ich eine recht einfache Lösung.
    Da ich denn Fall habe, daß ich aus einem anderem, als dem Form Thread, Events feuere, muss ich der Invoke Methode die Form übergeben.
    Da ich die Form nich extra als Parameter übergeben wollte, habe ich es folgendermaßen gemacht:

    VB.NET-Quellcode

    1. Private ReadOnly OwnerForm As Form
    2. Sub New()
    3. MyBase.New()
    4. #Region "Get OwnerForm"
    5. Dim declaringTypeFullName As String =
    6. New StackFrame(1).GetMethod.DeclaringType.FullName
    7. For Each type_ As Type In Assembly.GetCallingAssembly.GetTypes()
    8. If type_.FullName = declaringTypeFullName Then
    9. If type_.BaseType.FullName = "System.Windows.Forms.Form" Then
    10. OwnerForm = Application.OpenForms().Item(type_.Name)
    11. End If
    12. End If
    13. Next
    14. #End Region
    15. End Sub

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

    In der UC.Designer.vb steht wohl momentan noch drin: DeinUC : Inherits UserControl
    Du musst das ändern in: DeinUC : Inherits DeineBaseUCKlasse.
    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.
    Ich finde meins nachwievor am allereinfachsten:

    ErfinderDesRades schrieb:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Aktualisieren
    3. ucl1.Aktualisieren()
    4. ucl2.Aktualisieren()
    5. ucl3.Aktualisieren()
    6. End Sub
    also jedes ucl hat seine eigene Aktualisieren()-Methode
    Deine Antwort verstehe ich nicht.

    Haudruferzappeltnoch schrieb:

    Aber die Methode greift auf das Form1.feld zu, was ja für alle gleich ist und deswegen auf dem Form sitzt.
    Was für ein feld? was für alle gleich ist und auf Form1 sitzt?
    Die Methode greift auf drei Felder zu, nämlich ucl1, ucl2, ucl3. Ja, und die sitzen auf dem Form, wassonst?

    Kein Basisklassen-Gehampel, kein Interface, kein Event, kein durchlauf mit Reflection or whatever.

    Zitierfehler behoben ~VaporiZed

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

    Damit ist gemeint, dass die UCs auf die/das MainForm-Variable/-Feld namens feld zugreifen (sollen).
    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.
    Tja, dann ist die nächste Frage, ob es bei dem einen Feld bleibt oder ob irgendwann noch was dazukommen soll, weswegen das ganze Form als Parameter übergeben werden soll. Ist ja alles noch etwas nebulös/abstrakt.
    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.
    @VaporiZed Jou. Und dann wird eine gemeinsame Basisklasse oder ein Interface wieder interessant.
    @Haudruferzappeltnoch Wie viele unterschiedliche solche Controls soll es denn geben?
    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!
    @ErfinderDesRades Ich denke wohl zu kompliziert, das sieht erstmal umsetzbar aus.

    @RodFromGermany Es werden erstmal 6 Controls sein. Aber der Punkt ist die Erweiterbarkeit. Es ist nicht unwahrscheinlich das irgendwann mal eins dazukommt.

    @VaporiZed Es wird sicher bei dem einen Feld bleiben, das feld selbst wird sich verändern. Es wird doch gar nicht das ganze Form übergeben?

    Ich bastel nochmal dran und frage nochmal nach

    Haudruferzappeltnoch schrieb:

    Es wird doch gar nicht das ganze Form übergeben?
    Richtig, dann reicht es, das feld als Parameter zu übergeben, wenn nur dieses manipuliert werden soll, also so, wie EdR schrieb. Ich meinte nur, dass das Form als Parameter übergeben werden sollte, wenn weitere Bestandteile des Forms manipuliert werden sollen.
    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.