VB.NET Labelnummer als Variable

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    VB.NET Labelnummer als Variable

    Ich möchte die Farbe der Labels in meinem Programm nach gewisser Aktion ändern.
    Grundsätzlich klappt das auch mit
    Me.Controls("label" & labelnr).ForeColor = Color.Red
    Dies klappt allerdings nur so lange, als die Label direkt im Hauptprogramm sind. Da bei mir die Label aber zu 99% auf unterschiedlichen Tabs (Tab Control) sind, klappt es nicht. Sobald ich ein Label auf einem Tab Control ansprechen möchte, wirf es ein "Object reference not set to an instance of an object" raus.
    Wie muss der Aufruf hier genau aussehen?
    Willkommen im Forum. :thumbup:

    ConfGen schrieb:

    Wie muss der Aufruf hier genau aussehen?
    Wie sieht Dein bisheriger Code aus?
    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!
    Ich hab mir zum Testen ein kleines Programm geschrieben.

    Quellcode

    1. Public Class Form1
    2. Dim labelnr As String = 0
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. If labelnr <> "0" Then
    5. Me.Controls("label" & labelnr).ForeColor = Color.Black
    6. End If
    7. labelnr += 1
    8. Me.Controls("label" & labelnr).ForeColor = Color.Red
    9. End Sub
    10. End Class


    Das Form hat 10 Label. Label 1-3 sind direkt auf dem Form. Label 4-10 sind in einem Tab Control auf Tab1.



    Den Button kann ich dann exakt drei Mal klicken und die Farbe von Label 1-3 ändert sich problemlos. Beim vierten Klick kommt die Fehlermeldung.

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

    Guten Tag ConfGen

    Willkommen.

    Es ist zwar eine eher primitive Lösung, aber sie funkst. Natürlich gibt es noch viele andere Lösungen, aber ich denke als erster Ansatz dient dieser vollkommen seinem Zweck.


    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Public Class Form1
    4. Private intCount As Integer = 0
    5. Private lstLabel As List(Of Label)
    6. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    7. If intCount > 7 Then intCount = 0
    8. If Not intCount = 0 Then
    9. lstLabel(intCount - 1).ForeColor = Color.Black
    10. lstLabel(intCount - 1).Text = "Color Black"
    11. End If
    12. intCount += 1
    13. lstLabel(intCount - 1).ForeColor = Color.Red
    14. End Sub
    15. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    16. lstLabel = New List(Of Label)
    17. lstLabel.Add(Me.Label1)
    18. lstLabel.Add(Me.Label2)
    19. lstLabel.Add(Me.Label3)
    20. lstLabel.Add(Me.Label4)
    21. lstLabel.Add(Me.Label5)
    22. lstLabel.Add(Me.Label6)
    23. lstLabel.Add(Me.Label7)
    24. lstLabel.Add(Me.Label8)
    25. End Sub
    26. End Class



    Freundliche Grüsse

    exc-jdbi

    ConfGen schrieb:

    Ich hab mir zum Testen ein kleines Programm geschrieben.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim labelnr As String = 0
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. If labelnr <> "0" Then
    5. Me.Controls("label" & labelnr).ForeColor = Color.Black
    6. End If
    7. labelnr += 1
    8. Me.Controls("label" & labelnr).ForeColor = Color.Red
    9. End Sub
    10. End Class
    Kein schöner Code. Was zB sollen die ganzen Leerzeilen ohne Sinn?
    Und sowas:

    VB.NET-Quellcode

    1. Me.Controls("label" & labelnr).ForeColor = Color.Black
    sollte niemals auftreten. Gib deinen Labels vernünftige Namen - ohne Nummern.
    Das andere wurde ja schon gesagt:
    Vergiss den Zugriff über Controls(String), und pack die Labels, die du addressieren willst in eine List(Of Label).
    Dann weißt du, wo du sie findest, egal, welchen Namen sie haben, und du kannst die Namen sogar noch nachträglich verändern (Korrigieren!!) im Designer, ohne dass sie deswegen aus der List(Of Label) verschwinden würden.

    ConfGen schrieb:

    VB.NET-Quellcode

    1. Dim labelnr As String = 0
    Fang an mit Option Strict On, da sagt Dir das Studio, wie falsch Du mit den Datentypen umgehst.
    Hier:
    0 ist ein numerischer Wert, den Du einem String zuweist. Was soll das?
    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!
    Danke für die vielen Hinweise.
    1. Leerzeilen sind beim Copy&Paste reingekommen
    2. bei inzwischen knapp 600 Labels, macht weder ein nachträgliches Umbenennen, noch ein Einfügen in eine Liste Sinn. Ich denke der Aufwand wäre etwas groß
    3. Im ersten Schritt war die Variable auf als Integer deklariert. Bei den Tests habe ich aber mal verschiedene Dinge ausprobiert.

    Würde mich riesig über eine andere Lösung freuen, bei der ich nicht alle Label umbenennen oder auslisten muss.

    ConfGen schrieb:

    knapp 600 Label
    ist ein völliges Fehl-Design.
    Denk mal drüber nach, eine Tabelle zu (DataGridView) benutzen.
    Kannst Du mal von Deiner GUI einen Snapshot posten?
    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!
    @ConfGen Mach Dir pro Tab ein UserControl,
    und / oder
    mach Dir statt der GroupBoxen auch je ein UserControl.
    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!

    ConfGen schrieb:

    Beispiel
    findest Du bei Frau Google oder hier.
    Such noch weiter ("usercontrol", "usercontrol tutorial", ...) und Du wirst sehr viel finden.
    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!
    oder einfach Menu-Projekt-UserControl hinzufügen - und schon gehts los :D .

    Wichtig ist, dass UserControls aufzufassen, zu designen (im Designer) und zu behandeln sind wie eigenständige Forms.
    Der einzige Unterschied ist, ein Form ist ein TopLevel-Control - wird also direkt auffm Bildschirm angezeigt.

    Ein UserControl dagegen ist ein normales Control, was man aus der Toolbox aufs Form zieht.
    Dennoch bleibt es eigenständig, also im Code des einen Ucls hast du keinen Zugriff auf Variablen und Steuerelemente, die auf einem anderen Ucl liegen.
    Programmiere nicht gegen diese "Beschränkung" an, sondern nutze sie, um deine Anwendung in sinnvolle Funktionalitäts-Einheiten zu unterteilen.

    Von deim Bildle her würde ich den Code deines Main-Forms auf locker 10000 Zeilen schätzen - also vollkommen unwartbar :thumbdown: .
    Das ändert sich durch die Strukturierung - der Code verteilt sich auf möglichst sinnvolle Weise auf die verschiedenen Einheiten.
    Danke euch. Ich schau mir das mal (weiter) an.

    Schätzung lag übrigens kanpp daneben. Für ThinOS (das, was man in den Screenshots zum Teil sieht) sind es fast 25.000 Zeilen. Und dann kommen noch andere Betriebssysteme dazu. Insgesamt über 70.000 Zeilen Code.

    Was sich mir aber noch nicht erschließt, ist, warum klappt die Änderung des Label nicht, sobald es auf einem TabControl liegt.

    ConfGen schrieb:

    TabControl
    Da musst Du alle Änderungen fein säuberlich durchreichen.
    Mach Dir eine vernünftige Basisklasse für Deine UserControls, wo Du solch reinpacken kannst:

    VB.NET-Quellcode

    1. Public Class MyUserControl
    2. Inherits UserControl
    3. ' etwas tun
    4. End Class
    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!
    Guten Tag ConfGen

    Vielleicht noch einen Tip .. Es gibt die Dokumentengliederung, diese nutze ich noch viel, wenn ich konzeptionelle Änderungen im Design machen muss. Vielleicht eine Erleicherung.

    Jedoch wenn man es das Erste mal macht, kann man ziemlich schnell auch die Übersicht verlieren.

    Freundliche Grüsse

    exc-jdbi