For Each-Schleifen Problem(ch)en

  • VB.NET

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

    For Each-Schleifen Problem(ch)en

    Hi,

    ich habe eine Form in der mehr als 10 Pictureboxen und nun möchte ich diese dynamisch den Hintergrund ändern lassen.
    Wollte das mit einer For Each-Schleife lösen, aber genau da liegt das Problem. Ich habe nämlich keine Ahnung wie ich alle diese Pictureboxen durch eine For Each-Schleife bekomme.

    Kann mir da jemand behilflich sein?

    MFG
    For Each Control as control in Form1.Controls

    Dann mit If Control.GetType() is typeOf(PictureBox) prüfen, ob das Control eine Picturebox is.

    Dann nur noch das Control zur Picturebox parsen:
    Dim picBox as PictureBox = Ctype(Control, Picturebox)

    -
    Der Code is ausm Kopf geschrieben, könnten kleine Fehler drin sein, vom Prinzip her aber richtig.
    Hi Appix,


    erstmal danke für deine Hilfe!

    Allerdings habe ich ein Problem mit deinem Vorschlag und zwar erstens mal hier:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. For Each Control As Control In Me.Controls
    3. If Control.GetType() Is TypeOf(PictureBox) Then '<<<<<<<
    4. Dim picBox As PictureBox = CType(Control, PictureBox)
    5. MsgBox("Hallo", MsgBoxStyle.Critical, "!!!")
    6. End If
    7. Next
    8. End Sub


    Er gibt mir da einen Typenfehler aus, da ja Picturebox ein Typ und kein Ausdruck ist. Des weiteren wird, wenn ich diesen Teil umschreibe die If-Schleife garnicht durchlaufen.

    Komische Sache...
    Naja...wie gesagt ich habe das ausm Kopf geschrieben, deswegen ist mir ein Fehler unterlaufen:
    Es muss nicht TypeOf() heißen, sondern GetType()

    Das heißt letztendlich:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. For Each Control As Control In Me.Controls
    3. If Control.GetType() Is GetType(PictureBox) Then
    4. Dim picBox As PictureBox = CType(Control, PictureBox)
    5. MsgBox("Hallo", MsgBoxStyle.Critical, "!!!")
    6. End If
    7. Next
    8. End Sub
    Schau mal:

    VB.NET-Quellcode

    1. For Each i In DasControlInDemSichAllePictureBoxenBefinden.Controls.OfType(Of PictureBox)()
    2. 'Irgendwas mit i tun.
    3. Next


    @APPIX:
    Wenn keine tatsächliche Konvertierung erfolgen soll, sollte DirectCast() verwendet werden.

    Bei CType() wird zur Laufzeit versucht, das angegebene Objekt in den angegebenen Typ zu konvertieren.
    Dim Test As Integer = CType("123", Integer)
    Funktioniert.

    DirectCast() prüft zur Laufzeit nur, ob der Typ des angegebenen Wertes vom angegebenen Typ erbt.
    Dim Test As Integer = DirectCast("123", Integer)
    "Der Wert vom Typ "String" kann nicht in "Integer" konvertiert werden."
    Weil Integer nicht von String erbt.

    Das sollte geringfügig performanter sein (und irgendwo sinnvoller, weil man ja nicht wirklich konvertieren will).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Pack alle die betreffenden PictureBoxen in ein PictureBox-Array, das geschieht zur Compile-Zeit:

    VB.NET-Quellcode

    1. Private MyBoxArray() As PictureBox = { PictureBox1, PictureBox2, PictureBox3, PictureBox4 , ...}
    2. Private Sub xxx()
    3. For Each pb In MyBoxArray
    4. ' mit pb was tun
    5. Next
    6. 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
    zwischen <instance>.GetType() = GetType(<Type>) und TypeOf <instance> Is <Type> ist übrigens ein riesiger Unterschied. Während das Erste explizit die Typen auf Gleichheit überprüft, überprüft das Zweite, ob <instance> vom Typ <Type> ist, also wird auch überprüft, ob ein Interface implementiert wird oder der Typ von <instance> von <Type> abgeleitet wurde. Bspw.:
    [GetType()] = GetType(Form) gibt False, wenn Me eine von Form abgeleitete Klasse ist, bei TypeOf Me Is Form gibt es True zurück.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Inherits Form
    3. Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    4. If [GetType]() = GetType(Form) Then
    5. MessageBox.Show("Sollte nicht erreicht werden, da Me nicht vom Typ Form ist, sondern davon abgeleitet.")
    6. End If
    7. If TypeOf Me Is Form Then
    8. MessageBox.Show("Form1 ist von Form abgeleitet.")
    9. End If
    10. End Sub
    11. End Class


    RodFromGermany's Lösung ist mMn. trotzdem besser.

    Gruß
    ~blaze~