Code polieren

  • VB.NET

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von Eistee.

    Code polieren

    Hi,

    Ich bin gerade dabei ein altes Projekt zu überarbeiten und hänge nun an einer stelle fest.
    Irgendwie bin ich mir nicht sicher ob dies so die beste Lösung ist und wollte einfach mal hören was ihr so denkt:

    Es geht um Menu Einträge welche mit den Pfeiltasten ausgewählt werden können.
    Die Einträge liegen in einer List (Of T) und müssen bei der Auswahl "überwacht" werden.
    Überwacht im dem Sinne dass es einige Einträge gibt, welche nicht auswählbar sind, diese müssen übersprungen werden.
    Natürlich muss auch darrauf geachtet werden das wenn man am ende angekommen ist, es auf der anderen Seite der Liste wieder los geht.

    Hier mal der Code:

    VB.NET-Quellcode

    1. 'Rauf
    2. If ruff.Evaluate() Then
    3. Selected -= 1
    4. If Selected < 0 Then
    5. Selected = Einträge.Count - 1
    6. End If
    7. If Einträge(Selected).Enabled = False Then
    8. Dim fertig As Boolean = False
    9. For x = Selected To 0 Step -1
    10. If Einträge(x).Enabled = True Then
    11. Selected = x
    12. Exit For
    13. End If
    14. Next
    15. If fertig = False Then
    16. Selected = Einträge.Count - 1
    17. For y = Selected To 0 Step -1
    18. If Einträge(y).Enabled = True Then
    19. Selected = y
    20. Exit For
    21. End If
    22. Next
    23. End If
    24. End If
    25. End If
    26. 'Runter
    27. If runner.Evaluate() Then
    28. Selected += 1
    29. If Selected >= Einträge.Count Then
    30. Selected = 0
    31. End If
    32. If Einträge(Selected).Enabled = False Then
    33. Dim fertig As Boolean = False
    34. For x = Selected To Einträge.Count - 1
    35. If Einträge(x).Enabled = True Then
    36. Selected = x
    37. fertig = True
    38. Exit For
    39. End If
    40. Next
    41. If fertig = False Then
    42. Selected = 0
    43. For y = 0 To Einträge.Count - 1
    44. If Einträge(y).Enabled = True Then
    45. Selected = y
    46. Exit For
    47. End If
    48. Next
    49. End If
    50. End If
    51. End If


    Würdet ihr das anders Lösen?
    Mir ist bis jetzt noch nichts anderes eingefallen, ohne das man gleich das ganze Menu neu schreiben muss.
    Gezeichnet wird nur ein String.

    Welches gerade Selektiert ist, muss man wissen um das Selektierte etwas größer zu zeichnen.
    So wie für den Fall das Enter gegrückt wird, also was darrauf dann folgt (Beenden, Optionen anzeigen, ...).
    ich weis nicht wie deine menü ausschaut, aber du kannst in eine Schleife "rauf":
    - abfragen ob Eintrag Enabled = True/False
    - wenn False, dann Eintrag überspringen
    - wenn letzter/erster Eintrag erreicht, dann bleib stehen oder springe zu ersten/letzten Eintrag

    das gleiche gilt für "runter".
    Du hast mich falsch verstanden, in meine beschreibung brauchst nur 2 schleifen, in deine gepostete code sind's 4 schleifen.

    Ansatz:
    - Du brauchst eine Globale Booleanische Variable um abzufragen ob der Eintrag Enabled True/False
    - Du brauchst eine Globale Integer/Long Variable (je nach anzahl die Einträgen) für Gesammte Anzahl die Einträge und eine Zählvariable (wie du schon in dene code hast <<Selected>> )

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

    Ok jetzt hab ich es verstanden, nur bekomme ich das gerade nicht so umgedreht das es für beide fälle greift.
    Da ich ja 2 "nicht funsionierbare" Abfragen habe, Runter und Hoch, habe ich die Schleifen in einen extra Sub verschoben.
    Jetzt hapert es nur noch etwas beim umstellen.

    Edit: Also Ich sehe da irgendwie nicht die Möglichkeit die Schleifen auf zwei zu reduzieren, ohne das böse GoTo zu verwenden.
    Hoch:

    VB.NET-Quellcode

    1. 'Überprüft, ob überhaupt Einträge ausgewählt werden dürfen, da es sonst zu einer Endlosschleife kommt
    2. If Not Einträge.All(Function(i) Not i.DarfAusgewähltWerden) Then
    3. Do
    4. If Selected = 0 Then
    5. 'Wenn schon ganz oben, dann von unten wieder anfangen
    6. Selected = Einträge.Count - 1
    7. Else
    8. 'Sonst nach oben verschieben
    9. Selected -= 1
    10. End If
    11. 'So lange verschieben, bis ein auswählbarer Eintrag gefunden wurde
    12. Loop Until Einträge(Selected).DarfAusgewähltWerden
    13. End If

    Runter:

    VB.NET-Quellcode

    1. If Not Einträge.All(Function(i) Not i.DarfAusgewähltWerden) Then
    2. Do
    3. If Selected = Einträge.Count - 1 Then
    4. Selected = 0
    5. Else
    6. Selected += 1
    7. End If
    8. Loop Until Einträge(Selected).DarfAusgewähltWerden
    9. End If
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    - Du hast z.b 5 Einträge, 2 davon sind Enabled = False
    - Beim Start wird der erster Eintrag markiert
    - mit Buttons verschiebst du markierung auf/ab
    Du brauchst drei globale variablen, mit deren prüfst du ob Eintrag Enabled = True/False, ob letzter/ersten eintrag erreicht wurde und zählvariable.

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

    SystemUnknow schrieb:

    Booleanische Variable


    Aus dem Stamm der Booleaner, die die booleanische Sprache sprechen? ;)

    Eistee schrieb:

    Was?!

    Na bei eurem Code überseht ihr alle das offensichtliche ... Nämlich, dass am "Ende" der Liste einfach weitergearbeitet werden kann, wenn man mit Modulo arbeitet. Es ist also unnötig zu prüfen, ob man am Ende der Liste ist.

    Habe die Liste 5 Elemente und selektiert sei das zweite (also index 1):

    Zähle man vom aktuellen index+1 bis index+5
    2 ok
    3 ok
    4 ok
    5 ... -> modulo! -> 0
    6 -> 1

    Ich überprüfe also - ohne prüfen ob ich am "Ende" bin - die Indizes von 2 bis 4 und danach die von 0 bis 1

    PS: Das "rückwärts" zählen ist im Prinzip genau trivial, erfordert aber einen kleinen "Trick" ;)

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

    Eistee schrieb:

    Edit: Also Ich sehe da irgendwie nicht die Möglichkeit die Schleifen auf zwei zu reduzieren, ohne das böse GoTo zu verwenden.

    naja, man erfindet eine Variable aStep As Integer, und die ist bei rauf -1, und bei runner +1.

    und die added man immer, in derselben Schleife. So kann aus 2 Scheifen eine werden. Dazu noch picoflops Modulo-Trick, dann wird das ganze nicht unschnuckelig ;)
    So, das Ganze mal als Beispiel und zusammengekürzt:

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Public Class Form2
    3. Private Class EinDing
    4. Public Text As String
    5. Public Enabled As Boolean = True
    6. Public Sub New(ByVal t As String)
    7. Text = t
    8. End Sub
    9. End Class
    10. Private DingListe As New List(Of EinDing)
    11. Private Selektiert As Integer = -1
    12. Private Function verfuegbar() As IEnumerable(Of Integer)
    13. Return From i
    14. In Enumerable.Range(Selektiert + 1, DingListe.Count - 1)
    15. Let k = i Mod DingListe.Count
    16. Where DingListe(k).Enabled
    17. Select k
    18. End Function
    19. Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    20. For i = 1 To 10
    21. Dim ed As New EinDing(i.ToString)
    22. If i Mod 3 = 0 Then ed.Enabled = False
    23. DingListe.Add(ed)
    24. Next
    25. Selektiert = verfuegbar.First
    26. Label1.Text = Selektiert.ToString
    27. End Sub
    28. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    29. Selektiert = verfuegbar.First
    30. Label1.Text = Selektiert.ToString
    31. End Sub
    32. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    33. Selektiert = verfuegbar.Last
    34. Label1.Text = Selektiert.ToString
    35. End Sub
    36. End Class