Usercontrol mit List of Klasse - Codeseitiges hinzufügen

  • VB.NET
  • .NET (FX) 4.0

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

    Usercontrol mit List of Klasse - Codeseitiges hinzufügen

    Hallo Com,

    in meinem UserControl habe ich eine List of Klasse. Die sieht z.B. so aus wie hier:List (Of String) als Property mit _1 und _2 als String.
    Wie kann ich denn Codeseitig z.B. in Form1 _1 und _2 hinzufügen?
    Also z.B.

    VB.NET-Quellcode

    1. dim ucontrol as new usercontrol1
    2. usercontrol1.items.add("TEST1", "TEST2")
    @ErfinderDesRades Datentyp: String. Das Usercontrol heißt angenommen "Usercontrol1"
    Im Usercontrol soll die List of verwendet werden. In der Form1 soll die List of gefüllt werden.

    Im Endeffekt soll das ganze so aussehen:

    Form1

    VB.NET-Quellcode

    1. 'Im Load Event
    2. usercontrol1.items.add("TEST1", "TEST2")


    Das Usercontrol

    VB.NET-Quellcode

    1. 'hier steht Inhalt des Usercontrols
    2. '...
    3. Public items as list(of Test)
    4. public sub new
    5. end sub
    6. 'meine Idee zum durchreichen
    7. public sub fill(byval t1 as string, byval t2 as string)
    8. items.add(new Test(t1, t2)) '?? - klappt aber nicht wirklich
    9. end sub
    10. public Class Test
    11. public property t1 as string
    12. public property t2 as string
    13. '+Public sub new
    14. end class


    klyer schrieb:

    Im Endeffekt soll das ganze so aussehen:

    Form1

    VB.NET-Quellcode

    1. 'Im Load Event
    2. usercontrol1.items.add("TEST1", "TEST2")

    Das wird so nicht gehen, denn userControl1.Items ist vom Typ List(Of String), und deren Add-Methode ist numal anders.
    Guck doch einfach nach, wie die Add-Methode richtig geht, dann weisst du wies richtig geht.
    Weißt du, wie man Methoden nachguckt?
    VisualStudio richtig nutzen (Google ist nicht deine Mami)
    Habs jetzt. Danke @nafets3646
    Auch danke @ErfinderDesRades für den nützlichen Link.

    VB.NET-Quellcode

    1. Public Class UserControl1
    2. Private Items As New List(Of Test)
    3. Public Sub New()
    4. ' Dieser Aufruf ist für den Designer erforderlich.
    5. InitializeComponent()
    6. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    7. Items = New List(Of Test)
    8. 'Items.Add(New Test("Hallo", "Welt"))
    9. 'Items.Add(New Test("Hallo", "Welt"))
    10. End Sub
    11. Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    12. MyBase.OnPaint(e)
    13. Dim y As Integer
    14. For Each I In Items
    15. 'Dim y As Integer
    16. e.Graphics.DrawString(I.T1 & " " & I.T2, Font, Brushes.Red, 10, y)
    17. y += 10
    18. Next
    19. End Sub
    20. Public Sub fill(ByVal t1 As String, ByVal t2 As String)
    21. Items.Add(New Test(t1, t2))
    22. End Sub
    23. Public Class Test
    24. Public Property T1 As String
    25. Public Property T2 As String
    26. Public Sub New(ByVal t1 As String, ByVal t2 As String)
    27. Me.T1 = t1
    28. Me.T2 = t2
    29. End Sub
    30. End Class
    31. End Class


    VB.NET-Quellcode

    1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. UserControl11.fill("Hallo", "Welt")
    3. End Sub

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

    @klyer Wenn Du Text sehen willst, musst Du das UserControl nach dem Besücken mit Daten updaten:

    VB.NET-Quellcode

    1. Public Sub fill(ByVal t1 As String, ByVal t2 As String)
    2. Items.Add(New Test(t1, t2))
    3. Me.Update()
    4. End Sub
    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!
    Hi
    am besten wäre, du würdest eine Klasse von System.Collections.ObjectModel.Collection(Of T) erben lassen und dort an das UserControl weiterleiten, sobald sich Items verändern. Das geht, indem du die Methoden ClearItems, InsertItem, RemoveItem und SetItem überschreibst, das im Konstruktor der Klasse übergebene UserControl darüber informierst, indem du bspw. Methoden (mit dem Friend-Modifikator) aufrufst und dort das Item und den Index übergibst. Clear kannst du in zwei Schritten behandeln: Clearing und Cleared. Clearing wird vor dem Aufruf von MyBase.ClearItems(), Cleared danach aufgerufen. Invalidate kannst du dazu verwenden, bestimmte Bereiche des Controls neuzeichnen zu lassen.

    Gruß
    ~blaze~
    @klyer
    Fehler noch:
    In deiner Paint Routine wird die Variable "y" nach jedem Schleifendurchgang wieder auf 0 gesetzt (Dim y as Integer).
    Das Erhöhen am Ende der Schleife um 10 bringt also nix.
    Deklariere y außerhalb der Schleife.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Das liegt an der Art der Variablenhaltung. Die Variable wird effektiv (d.h. im kompilierten Code) nicht an der Stelle deklariert, an der sie im Code steht und der Platz bleibt für alle y identisch. Da nach dem ersten Durchlauf keine Zuweisung mehr erfolgt, bleibt der Wert des alten Durchlaufs fälschlicherweise bestehen.

    Eine geeignete Webresource ist prinzipiell bereits die MSDN, aber hier:

    VB.NET-Quellcode

    1. Public Class MyUserControlItemsCollection
    2. Inhertis System.Collections.ObjectModel.Collection(Of MyItem)
    3. Private _control As MyUserControl
    4. Public Property Control As MyUserControl
    5. Get
    6. Return _control
    7. End Get
    8. Private Set(value As MyUserControl)
    9. If value Is Nothing Then Throw New ArgumentNullException("Control")
    10. _control = value
    11. End Set
    12. End Property
    13. Friend Sub New(control As MyUserControl)
    14. If control Is Nothing Then Throw New ArgumentNullException("control")
    15. Me.Control = control
    16. End Sub
    17. Protected Overrides Sub InsertItem(index As Integer, item As MyItem)
    18. MyBase.InsertItem(index, item)
    19. 'Control informieren
    20. Me.Control.SubmitItemInserted(index, item)
    21. End Sub
    22. Protected Overrides Sub RemoveItem(index As Integer)
    23. Dim oldItem As MyItem = Me.Items(index)
    24. MyBase.RemoveItem(index)
    25. 'Control informieren
    26. Me.Control.SubmitItemRemoved(index, oldItem)
    27. End Sub
    28. '...
    29. End Class
    30. Public Class MyUserControl
    31. Inherits Control
    32. Private _items As MyUserControlItemsCollection
    33. 'Die Items in Items sollen vom Designer serialisiert werden, damit die Elemente richtig übernommen werden
    34. <System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)> _
    35. Public ReadOnly Property Items As MyUserControlItemsCollection
    36. Get
    37. Return _items
    38. End Get
    39. End Property
    40. Public Sub New()
    41. InitializeComponent()
    42. _items = new MyUserControlItemsCollection(Me)
    43. End Sub
    44. 'Wird aufgerufen, sobald ein Element in die MyUserControlItemsCollection eingefügt wird.
    45. Friend Sub SubmitItemInserted(index As Integer, item As MyItem)
    46. OnItemInserted(index, item)
    47. End Sub
    48. 'Überschreibbar machen, damit erbende Klassen das Verhalten verändern können
    49. Protected Overridable Sub OnItemInserted(index As Integer, item As MyItem)
    50. Me.Invalidate(GetItemBounds(item))
    51. End Sub
    52. Public Function GetItemBounds(item As MyItem) As Rectangle
    53. If item Is Nothing Then Throw New ArgumentNullException("item")
    54. End Function
    55. Friend Sub SubmitItemRemoved(index As Integer, item As MyItem)
    56. End Sub
    57. '...
    58. End Class


    Usw. Musst halt die Logik beachten.

    Gruß
    ~blaze~
    Ok danke für die Aufklärung. Mich hatte das nämlich etwas verwirrt. Aber eben getestet. Würde y nach dem Deklarieren auch initialisiert werden (zB mit = 0, was ich eigentlich automatisch erwartet hätte) wäre y immer 0 und würde halt am Ende der Schleife um 10 erhöht werden (dann wieder 0).

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Ja: List(Of T) informiert das Control nicht, wann es neugezeichnet werden soll. Dem Benutzer sollte man dies nicht überlassen, das sollte das Control schon selber übernehmen.
    Alternativ kann man sich auch gleich die Mühe machen, Datenbindung zu implementieren, dafür sollte man aber eine große Menge Zeit mitbringen.

    Gruß
    ~blaze~