For Each Schleife --> Textbox

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von FatFire.

    For Each Schleife --> Textbox

    Hallo zusammen,

    ich habe in meiner Anwendung ein Panel. Dort hinein werden Textboxes und Labels zur Laufzeit erstellt, wobei die Labels lediglich als Platzhalter dienen. Über die Dock = Top Eigenschaft, werden die Steuerelemente untereinander platziert.

    Nun benutze ich für die Textboxes folgenden Aufruf bei der Erstellung, um die Höhe der Box auf den beinhalteten Text anzupassen. Ich möchte nämlich Scollbars verhindern:

    VB.NET-Quellcode

    1. CreatedTB.Height = (CreatedTB.GetLineFromCharIndex(CreatedTB.TextLength) + 1) * CreatedTB.Font.Height

    Leider tritt das Verhalten auf, dass die Größe der Textboxes beim Ändern der Formgröße nicht automatisch angepasst werden, was ja auch logisch ist, daher wollte ich mir die Funktion ResizeEnd oder SizeChanged zur Hilfe nehmen. Dummerweise wird das Programm sporadisch beendet und es wird kein Fehler ausgegeben. Wenn ich die platzhaltenden Labels nicht zwischen die einzelnen Textboxes einfüge, scheint alles ohne Probleme zu funktionieren.

    Und so sieht das Ganze aus:

    VB.NET-Quellcode

    1. Private Sub Form1_ResizeEnd(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ResizeEnd
    2. For Each txtBox As TextBox In pnlMain.Controls
    3. If TypeOf txtBox Is TextBox Then
    4. txtBox.Height = (txtBox.GetLineFromCharIndex(txtBox.TextLength) + 1) * txtBox.Font.Height
    5. End If
    6. Next txtBox
    7. End Sub


    Aber irgendwie schmiert das Programm immer ab. Schuld sind die Labels, welche aber gar nicht angefasst werden sollen. Ich will lediglich alle die Höhe von den Textboxes im Panel ändern. Sonst nix.

    Was mache ich falsch?


    Viele Grüße,
    Pry
    Dateien umbenennen und nummerieren - nichts leichter als das!

    Basic File Renamer: 100%
    Controls beinhaltet eine Collection von Controls, nicht von Textboxen.
    Sobald ein anderes Control als eine Textbox existiert, wird es einen Fehler geben, da der Kompiler ein Label nicht implizit in eine Textbox konvertieren kann.

    -> For each C as Control in .Controls


    Gruß Mono
    Das ist meine Signatur und sie wird wunderbar sein!

    Pry schrieb:

    For Each txtBox As TextBox In pnlMain.Controls

    Geht so nicht. Das selektiert nämlich nicht alle Textboxen, sondern alle controls und behandelt dann jedes Control als Textbox.

    Mit LINQ:

    VB.NET-Quellcode

    1. Dim tbs As IEnumerable(Of TextBox) = From t In Me.Controls Where TypeOf t Is TextBox Select t
    2. For Each t As TextBox In tbs
    3. Next

    Alternativ kann man auch in der for Schleife prüfen, ob das aktuelle Control eine TB ist
    Die Controls sind eine Control-Collection, also solltest Du sich auch so durchlaufen:

    VB.NET-Quellcode

    1. For Each c As Control In Me.Controls
    2. If TypeOf c Is TextBox Then
    3. Dim txtBox As TextBox = DirectCast(c, TextBox)
    4. txtBox.Height = (txtBox.GetLineFromCharIndex(txtBox.TextLength) + 1) * txtBox.Font.Height
    5. End If
    6. Next c

    Dann klappts auch mit dem Nachbarn .... ähm, dem Code natürlich.
    Hallo,
    Geht so nicht. Das selektiert nämlich nicht alle Textboxen, sondern alle controls und behandelt dann jedes Control als Textbox.
    Ok, alles klar, dann kann ich das Verhalten auch nachvollziehen.
    Die Controls sind eine Control-Collection, also solltest Du sich auch so durchlaufen:

    VB.NET-Quellcode

    1. For Each c As Control In Me.Controls
    2. If TypeOf c Is TextBox Then
    3. Dim txtBox As TextBox = DirectCast(c, TextBox)
    4. txtBox.Height = (txtBox.GetLineFromCharIndex(txtBox.TextLength) + 1) * txtBox.Font.Height
    5. End If
    6. Next c

    Dann klappts auch mit dem Nachbarn .... ähm, dem Code natürlich.
    Funktioniert wunderbar. Vielen vielen Dank an euch!

    Viele Grüße,
    Pry
    Dateien umbenennen und nummerieren - nichts leichter als das!

    Basic File Renamer: 100%
    Na, das Du coole neue Techniken einsetzt, mit Befehlen die keiner versteht, der sich in der funktionalen Programmierung nicht auskennt und auch mit älteren Frameworks nicht kompatibel sind.

    Darüber hinaus kann der Compiler diese Befehle allerdings meist sehr effizient optimieren.

    Ja, ich bin neidisch auf die Leute, die mit Linq umgehen können...aber ich arbeite dran.

    Gruß FatFire

    PS: Benutz es ruhig. :)

    FatFire schrieb:

    mit Befehlen die keiner versteht, der sich in der funktionalen Programmierung nicht auskennt

    IMHO ist das ganze so deutlich besser "lesbar", insb. wenn man auch mit SQL gut befreundet ist.
    Entspricht übrigens auch dem "neuen" Paradigma: Sag nicht, WIE du etwas tun willst, sondern nur WAS du tun willst (und lass den Compiler die Einzelheiten regeln).
    Mit dem neuen Framework 4 kann LINQ auch parallel (.AsParallel) und man hat eine sehr einfach zu verwendende Multithreading Erweiterung.
    Sag nicht, WIE du etwas tun willst, sondern nur WAS du tun willst (und lass den Compiler die Einzelheiten regeln).

    Ja...funktionale Programmierung eben. Ist nun aber nicht unbedingt jedermanns Geschmack. Und es ist leider auch nicht jeder mit SQL befreundet.

    Mir persönlich gefällt es nicht, wie dieses Paradigma jetzt über Linq in VB und C# "reingehackt" wird. Dann doch lieber gleich funktional programmieren (ich persönlich setze mich jetzt schon seit einer Weile mit F# auseinander...aber irgendwie ist das mein persönlicher Brainfuck geworden ;( ).
    Es liegt nun mal nicht jedem. Jedem der es versteht, sei es natürlich wärmstens ans Herz gelegt. Ich war schon von Haskell und Erlang begeistert...ich habs nur nich kapiert :whistling:

    Gruß FatFire