Zur Laufzeit erstelltes Label in Panel anzeigen

  • VB.NET

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

    Zur Laufzeit erstelltes Label in Panel anzeigen

    Moin Gemeinde und ein erfolgreiches wie auch gesundes 2014 an alle :)

    Mit folgendem Code generiere ich Labels zur Laufzeit will sie in einem TableLayoutPanel anzeigen.
    Die einzelnen Felder sind 30 px breit und 20 px hoch.

    VB.NET-Quellcode

    1. Dim Labels As New Collections.Generic.List(Of Label)
    2. For i As Integer = 0 To Einträge - 1
    3. Labels.Add(New Label())
    4. Labels(i).AutoSize = False
    5. Labels(i).Width = 200
    6. Labels(i).Name = "Label" & i
    7. Labels(i).Text = "Ich bin Label Nummer " & i.ToString
    8. Me.TableLayoutPanel.Controls.Add(Labels(i), Col, Row)
    9. Next


    Der Code selber funktioniert, aber ich möchte die Labels mit Breite "200 px" über die Feldgrenzen anzeigen, also als Balken sozusagen.
    Nun kann ich natürlich mehrere Labels "nebeneinander" generieren, z.B. 7 x 30 = 210 = 7 Felder. Die sind aber an den Feldgrenzen unterbrochen.
    Wenn ich zur Entwurfzeit ein Label erstelle mit 200 px Breite, kann ich das ohne Probleme über das Panel legen; als durchgehendes Label.
    Geht das auch mit Labels, die zur Laufzeit generiert werden?

    Der nächste Schritt - wenn ich nun schon mal schreibe - soll sein, dass das erstelte Label angeklickt und damit eine Funktion ausgelöst werden kann. Der Label-Name wird später die ID eines Datensatzes sein und soll durch anklicken ausgelesen und angezeigt werden.

    Vielen Dank für Eure konstruktiven Antworten :)

    mepema2 schrieb:

    Geht das auch mit Labels, die zur Laufzeit generiert werden?
    Ja.
    Generiere ein entsprechendes Label im Designer und sieh Dir dessen Properties in der Prozedur InitializeComponents() in der Datei FormX.Designer.vb an.
    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 schnelle Antwort.

    Also: Ich habe irgendwo auf meiner Form ausserhalb des Panels ein Label 20x20 px in rot.
    Im Designer steht dazu

    VB.NET-Quellcode

    1. Me.lbl_rot1.BackColor = System.Drawing.Color.Red
    2. Me.lbl_rot1.Location = New System.Drawing.Point(90, 51)
    3. Me.lbl_rot1.Name = "lbl_rot1"
    4. Me.lbl_rot1.Size = New System.Drawing.Size(24, 20)
    5. Me.lbl_rot1.TabIndex = 1


    Dieses vorhandene Label wird zur Laufzeit versuchsweise so positioniert

    VB.NET-Quellcode

    1. TagBalken = 30
    2. PanelStartX = TableLayoutPanel1.Left + 86 + 15
    3. PanelStartY = TableLayoutPanel1.Top + 29
    4. lbl_rot1.Left = PanelStartX
    5. lbl_rot1.Top = PanelStartY + 31
    6. lbl_rot1.Width = TagBalken * 10


    Aber ein zur Laufzeit generiertes Label wird auch mit

    VB.NET-Quellcode

    1. Labels(i).Location = New System.Drawing.Point(220, 250)

    nur "hinter" dem Panel positioniert, ist also nicht sichtbar.

    ?( ?(

    mepema2 schrieb:

    ist also nicht sichtbar
    Dann hast Du den Designercode noch nicht vollständig durchgearbeitet.
    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!
    @mepema2:: Alle Zeilen, in denen lbl_rot1 vorkommt.
    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!
    Also, hier überall kommt "lbl_rot" vor:

    VB.NET-Quellcode

    1. Friend WithEvents lbl_rot1 As System.Windows.Forms.Label
    2. Me.lbl_rot1 = New System.Windows.Forms.Label
    3. 'lbl_rot1
    4. '
    5. Me.lbl_rot1.BackColor = System.Drawing.Color.Red
    6. Me.lbl_rot1.Location = New System.Drawing.Point(75, 383)
    7. Me.lbl_rot1.Name = "lbl_rot1"
    8. Me.lbl_rot1.Size = New System.Drawing.Size(21, 20)
    9. Me.lbl_rot1.TabIndex = 1
    10. '
    11. 'Form2
    12. Me.Controls.Add(Me.lbl_rot1)


    Also ich sehe nicht, wo der Zusammenhang mit dem Panel ist .. blind oder ahnungslos .. oder beides :(
    Zwischenzeitlich habe ich das Problem mit

    VB.NET-Quellcode

    1. Me.Controls.Add(Labels(i))
    2. Labels(i).BringToFront()

    gelöst. Ist das jetzt DIE Lösung oder nur ein Weg???

    Die zweite Frage war, wie ich bei einem generierten Label ein Click-Ereignis erzeugen/auswerten kann??
    Hast Du dazu auch eine Idee??

    Danke bisweilen :)
    Ungefähr. So fügst du der Form das Label hinzu und schiebst es vor alle anderen Controls.
    Das geht, aber ist nicht umbedingt richtig (sofern du das Label dem Panel hinzufügen willst)

    Mit dieser Zeile fügst du das erstelle Label der FORM zu:

    VB.NET-Quellcode

    1. Me.Controls.Add(Me.lbl_rot1)

    Wenn du also dein Label dem Panel hinzufügen willst, musst du dass auch tun:

    VB.NET-Quellcode

    1. PanelXYZ.Controls.Add(Me.lbl_rot1)

    Zu der zweiten Frage:
    Das funktioniert mit AddHandler

    Wenn du das TextGeändert Event erkennen möchtest, musst du dies wie folgt machen:

    VB.NET-Quellcode

    1. AddHandler lbl_rot1.TextChanged, AddressOf lbl_rot1_text_changed

    Du musst aber auch eine entsprechende Methode anlegen:

    VB.NET-Quellcode

    1. Private Sub lbl_rot1_text_changed(sender As Object, e As EventArgs)
    2. End Sub

    AddHandler macht grundsätzlich nichts anderes, als "Handles lbl_rot1.TextChanged" hier:

    VB.NET-Quellcode

    1. Private Sub lbl_rot1_TextChanged(sender As Object, e As System.EventArgs) Handles lbl_rot1.TextChanged
    2. End Sub

    Edit:
    Vollständigkeitshalber: Um ein solchen Event zu entfernen, kannst du RemoveHandlerverwenden.

    Grüsse
    Dancger
    MESS WITH THE BEST, DIE LIKE THE REST! :evil:
    n'paar Links: DNS Tools, Steal WA DB, Droidsheep...
    Hallo Dancger,

    vielen Dank für Deine Infos! :rolleyes:

    Ich muß die Labels nicht dem Panel hinzufügen.
    Das Panel bildet im Prinzip nur den Hintergrund für einen Kalender für 31 Tage. Die Labels zeigen für eine kleine Pension (Zimmervermietung)
    die belegten Zimmer an. Sie bekommen eine Zuordnung von der DB und müssen per Click halt die Einzeldaten anzeigen.
    Bei einer Neuvermietung wird halt ein neues Label generiert.

    Ich habe das jetzt so gelöst (Testaufbau):

    VB.NET-Quellcode

    1. Dim lbl As New Label
    2. lbl.Name = "lbl_3"
    3. lbl.BackColor = Color.Yellow
    4. lbl.Height = 15
    5. lbl.Width = 120 '// 3 Tage (3 * 30 px)
    6. AddHandler lbl.Click, AddressOf Label_Click
    7. lbl.Location = New System.Drawing.Point(PanelStartX + 134, PanelStartY + 77)
    8. Me.Controls.Add(lbl)
    9. lbl.BringToFront()


    Die X und Y Positionen sind später der Start des Labels und die Zeile innerhalb des Panels.

    Die Abfrage:

    VB.NET-Quellcode

    1. Sub Label_Click(ByVal sender As Object, ByVal e As EventArgs)
    2. Dim MyLabel As Label
    3. MyLabel = CType(sender, Label)
    4. MsgBox("CLICK auf " & MyLabel.Name)
    5. End Sub


    Das funktioniert einstweilen. Mal sehen, welche Problemchen noch auftauchen.....

    Besten Dank an alle, die sich ihren Kopf zerbrochen haben ;)

    mepema2 schrieb:

    per Click halt die Einzeldaten anzeigen.
    Wie wäre es mit einem ToolTip?
    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 RodFromGermany,

    aber es sollen die gesamten Kundendaten dabei aufgerufen werden. Das ist zuviel für einen ToolTip. Außerdem brauche ich ja die Möglichkeit, Anreise.... zu verändern. Als Idee aber vielleicht mit dem ToolTip den Gastnamen anzeigen lassen. Dann weiß man auf die Schnelle, wer gebucht hat (außer bei Müller....) :D

    Gruß

    mepema2 schrieb:

    Das ist zuviel für einen ToolTip.
    Oder Du machst Dir einen modalen Dialog mit BorderStyle = None, da kannst Du drin editieren und anzeigen was immer Du willst.
    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!
    ..was mir noch nicht klar ist: kann man ein dynamischs erzeugtes Label auch wieder Löschen/entfernen/degenerieren?

    Ich kann es unsichtbar machen und bei der nächsten Aktualisierung des Kalenders würde es dann verschwinden, daber löschen oder so wäre schöner :)
    Gehört zwar nur indirekt hierher, aber zum Projekt:
    Bei dieser UPDATE-Anweisung

    VB.NET-Quellcode

    1. Try
    2. If con.State = ConnectionState.Closed Then con.Open()
    3. Dim sqlString As String = "UPDATE Zimmer SET " & _
    4. "Delete = '1' WHERE BuID = " & BuchungsNummer & ""
    5. Dim upt As New OleDbCommand(sqlString, con)
    6. upt.ExecuteNonQuery()
    7. Catch ex As Exception
    8. MessageBox.Show("Fehler beim Löschen der Buchung: " & ex.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    9. Finally
    10. con.Close()
    11. End Try

    bekomme ich immer die Fehlermeldung "Fehler in der UPDATE-Anweisung".
    In "sqlString" steht ganz artig: "UPDATE Zimmer SET Delete = '1' WHERE BuID = 3"

    Ich suche schon seit Stunden nach dem Fehler, aber ich finde ihn nicht. Doch blind???
    In dem Feld 'Delete' soll lediglich die Zahl '1' eingetragen werden. Das Feld ist ein Integer-Feld. BuID ist Long Integer (Autowert). Die BuID = 3 gibt es auch, aber der Fehler soll in der UPDATE-Anweisung sein.

    ?( ?( ?( ?(

    mepema2 schrieb:

    Gehört zwar nur indirekt hierher
    Mach dazu mal einen Thread im Datenbank-Unterforum auf.
    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!

    Noch mal dynamische Labels

    Ich muß noch mal auf meine Label(ei) zurück kommen:

    In meinem Post #16 habe ich die Lösung zum löschen eines dynamischen Labels mit Click erreicht.
    Wie aber kann ich dynamische Labels per Code löschen? Woher bekomme ich die Information, die Labels anzusprechen?
    Über "Label.Name" geht das nicht. Welche Informationen brauche ich aus dem erstellten Label?

    Danke und Gruß aus Berlin
    Sieh Dir in der Prozedur InitializeComponents() an, was der Designer so macht. Das empfinde nach.
    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!