Klasse mit einem Panel als Übergabeparameter in der NEW()

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

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Klasse mit einem Panel als Übergabeparameter in der NEW()

    hallo

    es ist meine erste Frage und möchte mich kurz vorstellen,
    heiße Alois und bin ein etwas älterer Gelegenheitsprogrammierer, der mit
    ASM, C++, Borland Pascal ... groß geworden ist. Bin nun über Basic 6
    bei vb.net hängen geblieben, leider habe ich es mit der OOP noch nicht
    so recht, leider, weil es eigentlich eine super Sache ist.

    Aktuell
    möchte ich ein technisches Simulations-Programm erstellen (Forms), wo
    ich ein oder mehrere DIP Schalter platzieren möchte. Diese bestehen aus
    einfachen Buttons (Anzahl konfigurierbar) auf einem Panel
    platziert/zusammengefasst.

    Ich schreibe an einer DIP Schalter Klasse, und auf einer Form platziere ich per Designer ein Panel und
    rufe dann über den NEW() Konstruktor die DIP Schalter Klasse auf, hier
    übergebe ich dann auch das bereits auf der Forms platzierten Panel, nur
    leider funktioniert das nicht .

    Hier mal die Klasse:

    VB.NET-Quellcode

    1. Public Class DIP_Switch
    2. Enum Richtung
    3. N
    4. S
    5. O
    6. W
    7. End Enum
    8. Private Panel_Bank As Panel
    9. Private Panel_Nummer As UInt16
    10. Private DIPschalter_Anzahl As UInt16 'maximal 16 DipSchalter pro Bank
    11. Private DisplayNumerierung As Boolean 'Nummer wird unter dem DIP Schalter eingeblendet
    12. Private Startwert_Numerierung As UInt16 'Startwert der Nummer unter den DIP Schaltern
    13. Private Schalterstellung As Boolean 'wenn DIP unten, dann ist der Wert 0 oder 1
    14. Private Ausrichtung As Richtung
    15. Private Dezimalwert As UInt16 'Rückgabewert
    16. Private boolWert_DIPnr As BitArray 'Rückgabewert
    17. Private Bild_DIP_unten As Image = My.Resources.DIP_unten
    18. Private Bild_DIP_oben As Image = My.Resources.DIP_oben
    19. Private Bild_DIP_rechts As Image = My.Resources.DIP_rechts
    20. Private Bild_DIP_link As Image = My.Resources.DIP_links
    21. Public Sub New(mypanel As Panel, panelNumber As UInt16,
    22. dipswitchcount As UInt16, show_number As Boolean, startvalue As UInt16,
    23. switchpos As Boolean, direction As Richtung
    24. )
    25. Panel_Bank = New Panel
    26. Panel_Bank = mypanel
    27. Panel_Bank.Tag = panelNumber
    28. DIPschalter_Anzahl = dipswitchcount
    29. DisplayNumerierung = show_number
    30. Startwert_Numerierung = startvalue
    31. Schalterstellung = switchpos
    32. Ausrichtung = direction
    33. Dim butDIP() As Button = Nothing
    34. For i As UInt16 = 0 To DIPschalter_Anzahl - 1
    35. butDIP(i) = New Button With {
    36. .Parent = Panel_Bank
    37. }
    38. Next
    39. End Sub
    40. ReadOnly Property Decimalvalue As UInt16
    41. Get
    42. Return Dezimalwert
    43. End Get
    44. End Property
    45. Next
    46. End Sub
    47. End Class


    und hier der Aufruf von Forms:

    VB.NET-Quellcode

    1. Public Class Form_Test
    2. Private Sub Form_Test_Load(sender As Object, e As EventArgs) Handles Me.Load
    3. Dim Dezimalwert As UInt16
    4. Dim DipSchalterBank As New DIP_Switch(Panel1, 1, 8, False, 0, False, DIP_Switch.Richtung.N)
    5. Dezimalwert = DipSchalterBank.Decimalvalue
    6. End Sub
    7. End Class


    Fehler: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.


    Freue mich, wenn mir das wer erklären könnte, was ich falsch mache.

    Gruß,
    Alois


    P.S.: cool wäre es, wenn man das Ganze als eigenes CustomControl dann verwenden kann (Teil der Toolbox). Aber das ist dann der letzte Schritt.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ORTECH“ ()

    Willkommen im Forum. :thumbup:

    ORTECH schrieb:

    Aber das ist dann der letzte Schritt.
    Das sollte sogar der erste Schritt sein.
    Mach Dir ein UserControl mit all Deinem Zeugs und dann spiele damit rum.
    In welcher Zeile Deines Codes kommt dieser Fehler?
    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!
    @ORTECH Dein Code ist als solcher nicht testbar, da kommen Bildchen vor usw., da wäre das komplette Projekt, bereinigt (ohne obj-, bin- und vs-Verzeichnisse) gezippt anzuhängen:
    Erweiterte Antwort => Dateianhänge => Hochladen.
    Doch zuvor machst Du erst mal Option Strict On:
    Visual Studio – Empfohlene Einstellungen
    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!
    Option strict On ist eingeschaltet und Fehler sind ausgebessert bis auf einen, diesen hier. Da komm ich nicht drauf:

    VB.NET-Quellcode

    1. Private Sub ClickMethode(ByVal sender As System.Object, ByVal e As System.EventArgs)
    2. Dim btn As Button
    3. If TypeOf sender Is Button Then
    4. btn = CType(sender, Button)
    5. If btn.Tag = 1 Then
    6. DirectCast(sender, Button).Tag = 0
    7. DirectCast(sender, Button).Image = Bild_DIP_unten
    8. Else
    9. DirectCast(sender, Button).Tag = 1
    10. DirectCast(sender, Button).Image = Bild_DIP_oben
    11. End If
    12. Dezimalwert = 0
    13. Dim cnt As Integer
    14. 'Dipschalterstellungen zu dezimal konvertieren
    15. 'zählen wieviele Buttons (DIPSchalter) sich auf dem Panel befinden
    16. For Each ctrl As Control In Panel_Bank.Controls
    17. If TypeOf ctrl Is Button Then cnt += 1
    18. Dezimalwert += CInt(ctrl.Tag) * (2 ^ (cnt - 1))
    19. Next
    20. Panel_Bank.Tag = Dezimalwert
    21. End If
    22. End Sub


    Zeile 8: Der Wizard (nennt man den so?) sagt mir, dass ein Is Operator nötig sei, wenn ich Is einfüge statt =, dann kommt die Fehlermeldung, dass ich keine Integer Werte verwenden kann. Derbtn.tag ist aber ein integer Wert uind kein String. Versteh ich nicht.

    Ich weiß weiters auch nicht, ob ich CTYPE oder DIRECTRCAST verwneden soll, lt. www gibts das 2 verschiedene Meinungen
    Versuche die Tag-Property(als String) zu einem Integer zu parsen, wenn das erfolgreich war, schauen ob der Wert 1 ist.

    VB.NET-Quellcode

    1. btn = CType(sender, Button)
    2. Dim tagIntValue As Integer
    3. If Integer.TryParse(btn.Tag.ToString(), tagIntValue) Then
    4. 'hat geklappt
    5. If tagIntValue = 1 Then
    6. End If
    7. End If


    Würde auch so gehen, aber das kann Fehler verursachen, wenn die konvertierung nicht klappt(wird eine Exception geworfen)
    If CInt(btn.Tag) = 1 Then

    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

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

    Die Erstellung meiner DipSchalter in einem auf einer Form plazierten Panel funktioniert soweit.
    Wenn ich einen DIP Schalter (Button) klicke, dann macht er das, was ich in der Klasse geschrieben hab.
    Nur wie frage ich das DIP Schalter Click-Event in der Form ab? Der DIP Schalter wird ja in der Klasse erstellt (und ebenso der Eventhandler samt Methode)...Wie macht man das am besten?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ORTECH“ ()

    ORTECH schrieb:

    Nur wie frage ich das DIP Schalter Click-Event in der Form ab?
    Das ist die falsche Herangehensweise.
    Wenn Du eine Pizza bestellst, siehst Du nicht alle 5 Minuten nach, ob der Bote da ist, Du wartest, bis er Klingelt. ;)
    Gib dem Control ein Event, das Du wirfst, wenn das Schalter Click-Event eintritt.
    Reiche es einfach durch:
    Kommunikation zwischen mehreren Forms per Event
    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!
    Das mit der Pizza hängt wohl vom Hunger ab ;).
    Ich verstehe schon, was du meinst, aber wie ich das code technisch umsetze, da hab ich keinen Tau.
    Wie gib ich dem Button-Array ein Event? Mit addhandler? Damit rufe ich die private Methode in der Klasse auf.

    Oder geht das mit:

    VB.NET-Quellcode

    1. Public Event MeinEigenesEvent(ByVal sender As Object, ByVal e As MeinEigenesEventArgs)


    Das hab ich grad woanders hier im Forum gelesen.
    Aber wie implementiere ich das genau in der Klasse und wie bekomm ich das Event in der Form mit?

    Hier der aktuelle Stand meiner Klasse:

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Drawing.Design
    3. Public Class DIP_Switch
    4. Enum Richtung
    5. horizontal
    6. vertikal
    7. End Enum
    8. Private Panel_Bank As Panel
    9. Dim butDIP(15) As Button 'maximal 16 DIP Schalter
    10. Private DIPschalter_Anzahl As Integer 'maximal 16 DipSchalter pro Bank
    11. 'Private Schalterstellung As Boolean 'false= wenn DIP unten, dann ist der Wert 0, true= wenn DIP unten ist er 1
    12. Private Ausrichtung As Richtung ' graifische Ausrichtung der DIPSchalterbank
    13. Private Dezimalwert_normal, Dezimalwert_invertiert As Double 'Rückgabewerte, einmal von links nach rechts gewandelt bzw zurück (invertiert)
    14. Private Bild_DIP_unten As Image = My.Resources.DIP_down
    15. Private Bild_DIP_oben As Image = My.Resources.DIP_up
    16. Private Bild_DIP_rechts As Image = My.Resources.DIP_right
    17. Private Bild_DIP_links As Image = My.Resources.DIP_left
    18. Public Sub New(mypanel As Panel, dipswitchcount As UInt16, direction As Richtung)
    19. Panel_Bank = mypanel
    20. DIPschalter_Anzahl = dipswitchcount
    21. Ausrichtung = direction
    22. 'Schalterstellung = switchpos
    23. For i As Integer = 0 To (DIPschalter_Anzahl - 1)
    24. butDIP(i) = New Button
    25. With butDIP(i)
    26. .Parent = Panel_Bank
    27. Select Case Ausrichtung
    28. Case Richtung.horizontal
    29. .Top = 0
    30. .Size = New Size(CInt(Panel_Bank.Width / DIPschalter_Anzahl), Panel_Bank.Height)
    31. .Left = CInt(Panel_Bank.Width / DIPschalter_Anzahl * i)
    32. .Image = Bild_DIP_unten
    33. Case Richtung.vertikal
    34. .Left = 0
    35. .Size = New Size(Panel_Bank.Width, CInt(Panel_Bank.Height / DIPschalter_Anzahl))
    36. .Top = CInt(Panel_Bank.Height / DIPschalter_Anzahl * i)
    37. .Image = Bild_DIP_rechts
    38. End Select
    39. .Tag = 0 'Schalterstellung
    40. AddHandler .Click, AddressOf ClickMethode
    41. End With
    42. Next
    43. End Sub
    44. Private Sub ClickMethode(ByVal sender As System.Object, ByVal e As System.EventArgs)
    45. Dim btn As Button
    46. If TypeOf sender Is Button Then
    47. btn = CType(sender, Button)
    48. Select Case CInt(btn.Tag)
    49. Case 1 : DirectCast(sender, Button).Tag = 0
    50. If Ausrichtung = Richtung.horizontal Then DirectCast(sender, Button).Image = Bild_DIP_unten
    51. If Ausrichtung = Richtung.vertikal Then DirectCast(sender, Button).Image = Bild_DIP_rechts
    52. Case 0 : DirectCast(sender, Button).Tag = 1
    53. If Ausrichtung = Richtung.horizontal Then DirectCast(sender, Button).Image = Bild_DIP_oben
    54. If Ausrichtung = Richtung.vertikal Then DirectCast(sender, Button).Image = Bild_DIP_links
    55. End Select
    56. Dezimalwert_normal = 0
    57. Dezimalwert_invertiert = 0
    58. Dim cnt As Integer
    59. 'Dipschalterstellungen zu dezimal konvertieren
    60. 'zählen wieviele Buttons (DIPSchalter) sich auf dem Panel befinden
    61. Dim Dipschalteranzahl = Panel_Bank.Controls.Count
    62. cnt = 0
    63. For Each ctrl As Control In Panel_Bank.Controls
    64. If TypeOf ctrl Is Button Then cnt += 1
    65. Dezimalwert_normal += CInt(ctrl.Tag) * (2 ^ (cnt - 1))
    66. Next
    67. cnt = Dipschalteranzahl + 1
    68. For Each ctrl As Control In Panel_Bank.Controls
    69. If TypeOf ctrl Is Button Then cnt -= 1
    70. Dezimalwert_invertiert += CInt(ctrl.Tag) * (2 ^ (cnt - 1))
    71. Next
    72. End If
    73. End Sub
    74. Public Event ButtonKlick(sender As System.Object, e As System.EventArgs)
    75. ReadOnly Property Decimalvalue(startcount As Boolean) As Double
    76. Get
    77. If startcount = False Then Return Dezimalwert_normal Else Return Dezimalwert_invertiert
    78. End Get
    79. End Property
    80. ReadOnly Property DipNo(dipnumber As Integer) As Boolean
    81. Get
    82. If dipnumber < 0 Or dipnumber > 15 Then
    83. Return False
    84. Exit Property
    85. End If
    86. If CInt(butDIP(dipnumber).Tag) = 1 Then Return True Else Return False
    87. End Get
    88. End Property
    89. End Class


    und der Form:

    VB.NET-Quellcode

    1. Option Strict On
    2. 'Imports DIP_Switch
    3. Public Class Form_Test
    4. Dim Dezimalwert As Double = 0
    5. Dim DipSchalterBank1 As DIP_Switch
    6. Dim DipSchalterBank2 As DIP_Switch
    7. Dim DipSchalterBank3 As DIP_Switch
    8. Private Sub Form_Test_Load(sender As Object, e As EventArgs) Handles Me.Load
    9. DipSchalterBank1 = New DIP_Switch(Panel1, 8, DIP_Switch.Richtung.horizontal)
    10. DipSchalterBank2 = New DIP_Switch(Panel2, 4, DIP_Switch.Richtung.vertikal)
    11. DipSchalterBank3 = New DIP_Switch(Panel3, 6, DIP_Switch.Richtung.horizontal)
    12. End Sub
    13. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    14. ' DipSchalterBank3.ClickMethode(sender, e)
    15. TextBox1.Text = DipSchalterBank1.Decimalvalue(True).ToString
    16. TextBox2.Text = DipSchalterBank2.Decimalvalue(True).ToString
    17. TextBox3.Text = DipSchalterBank1.DipNo(18).ToString
    18. End Sub
    19. End Class

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

    ORTECH schrieb:

    Ich verstehe schon, was du meinst, aber wie ich das code technisch umsetze, da hab ich keinen Tau.
    Das steht in meinem Link, musst Du nur auf Deine Klassen übertragen:
    Statt Form2 in dem Code nimmst Du Dein UserControl.
    Deine UserControls sollten in der Designer-Toolbar erscheinen, zieh sie auf Deien GUI.
    Mach ggf. zunächst ein kleines Testprogramm, wo Du den Umgang mit UserControls übst.
    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!
    Das mit der Erstelllung eines Usercontrol meinte ich nicht, das was ich brauche und nicht weiß wie umsetzen ist folgendes:

    ich erstelle in meiner Form ein Objekt meiner DIPSchalter Klasse, das Panel plaziere ich in er Form und die Klasse erzeugt mir ein oder mehrere DIP Schalter, also Buttons.
    Wenn ich nun einen dieser DIP Schalter Buttons klicke, kann ich dieses Klick Event in der FOrm nicht abfragen bzw. weiß ich nicht wie das geht.

    Die DipSchalter Buttons werden ja dynamisch erzeugt über die Klasse und somit habe ich nix, wie ich das Klick Event in der FOrm abfragen kann.

    Hoff ich habs jetzt besser erklärt...
    Innerhalb Deiner ClickMethode kannst Du Dein ButtonKlick-Event mit RaiseEvent ButtonKlick(me, EventArgs.Empty) feuern. Nun brauchst Du aber noch jemanden, der sich dafür interessiert. Dazu müsstest Du nach dem Erstellen eines Dip-Schalter-Objektes dessen ButtonKlick-Event mit einer "zuhörenden" Methode verknüpfen:

    VB.NET-Quellcode

    1. Private Sub Form_Test_Load(sender As Object, e As EventArgs) Handles Me.Load
    2. DipSchalterBank1 = New DIP_Switch(Panel1, 8, DIP_Switch.Richtung.horizontal)
    3. AddHandler DipSchalterBank1.ButtonKlick, AddressOf DeinEventHandler 'EventHandler = Zuhörermethode
    4. DipSchalterBank2 = New DIP_Switch(Panel2, 4, DIP_Switch.Richtung.vertikal)
    5. AddHandler DipSchalterBank2.ButtonKlick, AddressOf DeinEventHandler
    6. DipSchalterBank3 = New DIP_Switch(Panel3, 6, DIP_Switch.Richtung.horizontal)
    7. AddHandler DipSchalterBank3.ButtonKlick, AddressOf DeinEventHandler
    8. End Sub
    9. Private Sub DeinEventHandler(sender As Object, e As EventArgs)
    10. 'hier der Code, der ausgeführt werden soll, nachdem irgendein Button irgendeines Dip-Schalters gedrückt wurde
    11. End Sub
    Solltest Du weitere Informationen dem Eventpaket mitgeben wollen, werden diese in eine eigene EventHandlerklasse gepackt und mitgeliefert, siehe alles über Events.
    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.

    ORTECH schrieb:

    kann ich dieses Klick Event in der FOrm nicht abfragen
    Dann solltest Du Dich auf die Straße stellen und warten, bis der Pizza-Bote vorbeikommt. ;)
    Gib Deinem UserControl ein Event.
    Lass die MainForm dieses Event aboinieren.
    Wenn im UserControl geklickt wird, rufst Du RaisEvent auf.
    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!