Die Rückgängig Taste

    • VB.NET

    Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von Apfel.

      Die Rückgängig Taste

      Wenn der Benutzer stets alle Eingaben richtig macht braucht er sie nicht, ansonsten handelt es sich um eine nützliche Option welche eine Anwendung meist wesentlich komfortabler macht, die Rückgängig Taste...

      Im nachfolgenden ist eine Codierung eines kleinen Programmes zu finden in welcher eine solche Rückgängig Taste umgesetzt wurde, natürlich auch mit einer Wiederholen Option als Gegenstück.
      Der wesentliche Punkt des Programmes besteht darin das alle für den Programmablauf wichtigen Variablen über eine Struktur in eine einzige Variable zusammengefasst worden sind. Nach jedem Programmschritt welcher eine wesentliche Änderung mit sich bringt werden die Werte für diese Variable aktualisiert und die alten Werte an Speichervariablen übergeben.

      Der Quellcode spricht ansonsten für sich und ist an allen wichtigen Stellen mit Kommentaren versehen.

      Zunächst ein Screenshot: (Durch einige Label ist es möglich den Vorgang zu beobachten):




      Und der Quellcode:

      VB.NET-Quellcode

      1. Public Class frmForm1
      2. '----------Variablendeklaration----------
      3. 'Variablen für den Prozess des Rückgängigmachens
      4. Public W As New Werte
      5. Public W1 As New Werte
      6. Public W2 As New Werte
      7. Public W3 As New Werte
      8. 'Die Variablen welche rückgängig gemacht werden sollen
      9. 'werden in einer Struktur zusammengefasst
      10. Public Structure Werte
      11. Public Zahl1 As Integer
      12. Public Zahl2 As Integer
      13. Public Zahl3 As Integer
      14. End Structure
      15. 'Ein Zaehler für den ganzen Prozess
      16. Public RueckWieder As Integer = 3
      17. '------------Menüauswahl---------------
      18. 'Die Menüauswahl Rückgängig wurde getroffen
      19. Private Sub mnurg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnurg.Click
      20. 'Es besteht wieder die Möglichkeit etwas zu wiederholen
      21. mnuwh.Enabled = True
      22. 'Es wird überprüft welcher Schritt gültig ist
      23. 'Da sich RueckWieder ändert findet an den jeweiligen Stellen
      24. 'Ein Abbruch mit Exit Sub statt
      25. If RueckWieder = 3 Then
      26. W = W1
      27. RueckWieder -= 1
      28. LabelWerte()
      29. Label18.Text = RueckWieder
      30. Exit Sub
      31. End If
      32. If RueckWieder = 2 Then
      33. W = W2
      34. RueckWieder -= 1
      35. LabelWerte()
      36. Label18.Text = RueckWieder
      37. Exit Sub
      38. End If
      39. If RueckWieder = 1 Then
      40. W = W3
      41. RueckWieder -= 1
      42. mnurg.Enabled = False
      43. LabelWerte()
      44. Label18.Text = RueckWieder
      45. Exit Sub
      46. End If
      47. End Sub
      48. 'Die Menüauswahl Wiederholen wurde getroffen
      49. Private Sub mnuwh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuwh.Click
      50. 'Es besteht wieder die Möglichkeit etwas zu wiederholen
      51. mnurg.Enabled = True
      52. 'Es wird überprüft welcher Schritt gültig ist
      53. If RueckWieder = 1 Then
      54. W = W1
      55. RueckWieder += 1
      56. LabelWerte()
      57. Label18.Text = RueckWieder
      58. Exit Sub
      59. End If
      60. If RueckWieder = 0 Then
      61. W = W2
      62. RueckWieder += 1
      63. LabelWerte()
      64. Label18.Text = RueckWieder
      65. Exit Sub
      66. End If
      67. End Sub
      68. '-------------Hauptprogramm------------
      69. 'Die Form wird geladen
      70. Private Sub frmForm1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      71. 'Es werden Startwerte gesetzt
      72. mnurg.Enabled = False
      73. mnuwh.Enabled = False
      74. 'AnfangsZaehlerstand in Label
      75. Label18.Text = RueckWieder
      76. End Sub
      77. 'Ereignisse der einzelnen Buttons wenn diese gedrückt werden
      78. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      79. W.Zahl1 += 1
      80. Label1.Text = W.Zahl1
      81. End Sub
      82. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
      83. W.Zahl2 += 1
      84. Label2.Text = W.Zahl2
      85. End Sub
      86. Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
      87. W.Zahl3 += 1
      88. Label3.Text = W.Zahl3
      89. End Sub
      90. 'Es wurde ausgewählt das die eingebenen Werte übergeben werden sollen
      91. Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
      92. 'Der Zaehlerstand für Rueckwieder wird aktualisiert
      93. If RueckWieder < 3 Then
      94. RueckWieder += 1
      95. End If
      96. 'AktuelleZaehlerstand in Label
      97. Label18.Text = RueckWieder
      98. 'Aktivierung und Deaktivierung des Menüs Rückgängig
      99. If RueckWieder >= 3 Then
      100. mnuwh.Enabled = False
      101. Else
      102. mnuwh.Enabled = True
      103. End If
      104. mnurg.Enabled = True
      105. 'Wertübergabe
      106. W3 = W2
      107. W2 = W1
      108. W1 = W
      109. 'Zahlen und Label zurücksetzen
      110. 'Das setzen der Werte ist problemlos da nie
      111. 'eine ungewollte Wertübergabe dieser Zahlen stattfindet
      112. W.Zahl1 = 0
      113. W.Zahl2 = 0
      114. W.Zahl3 = 0
      115. Label1.Text = W.Zahl1
      116. Label2.Text = W.Zahl2
      117. Label3.Text = W.Zahl3
      118. 'Im Speicher
      119. 'Erste Reihe
      120. Label4.Text = W1.Zahl1
      121. Label5.Text = W1.Zahl2
      122. Label6.Text = W1.Zahl3
      123. 'Zweite Reihe
      124. Label7.Text = W2.Zahl1
      125. Label8.Text = W2.Zahl2
      126. Label9.Text = W2.Zahl3
      127. 'Dritte Reihe
      128. Label10.Text = W3.Zahl1
      129. Label11.Text = W3.Zahl2
      130. Label12.Text = W3.Zahl3
      131. End Sub
      132. 'Den Label die Werte zuordnen
      133. Private Sub LabelWerte()
      134. 'Aktuelle Reihe
      135. Label1.Text = W.Zahl1
      136. Label2.Text = W.Zahl2
      137. Label3.Text = W.Zahl3
      138. End Sub
      139. End Class




      Hier noch einmal das ganze zum ausprobieren:

      RueckgaengigTaste.rar

      Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „Dragonfly“ ()

      Also mit nem Stack haste den Vorteil dass du an sich alle veränderungen ewig oft abspeichern kannst und später Stück für Stück wieder herstellen kannst. Letzt endlich kannst du für jede Sache die evtl. rückgängig gemacht werden soll via Stack absichern.

      Hab mal nen kleines Beispiel geschrieben:

      VB.NET-Quellcode

      1. Public Class Form1
      2. Dim s1 As New Stack(Of Integer) 'Stack für rückgängig vom Typ Integer
      3. Dim s2 As New Stack(Of Integer) 'Stack für weiderherstellen vom Typ Integer
      4. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      5. s1.Push(Integer.Parse(l1.Text)) 'packt Daten (in dem Fall Integer) auf Stack 1
      6. l1.Text = t1.Text
      7. End Sub
      8. Private Sub b1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles b1.Click
      9. If s1.Count > 0 Then
      10. Dim t As Integer
      11. t = s1.Pop 'ließt Daten vom Stack 1 in einen temporären Integer
      12. s2.Push(Integer.Parse(l1.Text)) 'packt Daten (in dem Fall Integer) auf Stack 2
      13. l1.Text = t
      14. Else
      15. MsgBox("Keine Elemente im Stack")
      16. End If
      17. End Sub
      18. Private Sub b2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles b2.Click
      19. If s2.Count > 0 Then
      20. Dim t As Integer
      21. t = s2.Pop 'ließt Daten vom Stack 2 in einen temporären Integer
      22. l1.Text = t
      23. Else
      24. MsgBox("Keine Elemente im Stack")
      25. End If
      26. End Sub
      27. End Class


      Als Form benötigst du in dem Beispiel 3 Buttons (Eingabe (Button1), zurück (b1) und wiederherstellen (b2)),
      ein Textfield (t1) für die Eingabe und ein Label (l1) für zwischenausgabe.

      Ich hoffe, es hilft dir nen bisschen weiter. 8-)
      Also mit nem Stack haste den Vorteil dass du an sich alle veränderungen ewig oft abspeichern kannst und später Stück für Stück wieder herstellen kannst.


      Also das ist natürlich ein enormer Vorteil gegenüber meiner Lösung.
      Der Quellcode scheint mir auch wesentlich schlanker zu sein, vielen Dank.
      Ich denke in Zukunft werde ich das auch so handhaben :)
      Das Problem beim Stack ist, dass man immer nur den letzten runter "poppen" kann/sollte. Eine ordentliche History wird dadurch schwer. Für sowas sind wieder ArrayLists besser - heißt dann hald offiziell nicht mehr Pop ;)
      Als "Daten-Container" is am Besten eine Struct oder gleich eine Klasse (mit ordentlichn Konstruktoren und vielleicht ner ToString-Methode für's eine Info-Liste) am Besten geeignet =)
      @Onkelchrischi
      Mir fällt da jetzt spontan Paint ein...
      Man kann meist die letzten 3 Zeichenschritte wieder rückgängig machen, das dürfte vermutlich ein Stack sein.

      @Mad Andy
      Ein Array wäre jetzt die nächste sinnvolle Erweiterung, ich arbeite derzeit an einem Programm wo das dann auch so laufen wird.

      Dragonfly schrieb:

      Ein Array wäre jetzt die nächste sinnvolle Erweiterung


      warum ein Array?? eine sinnvolle ergänzung bzw. Alternative wäre ne einfache LinkedList!? Das ist doch deutlich einfacher zu handeln als nen Array. Und für ne Chronik wie in Photoshop o.ä. optimal, da man eben Zustände herstellen kann ohne wie beim Stack von hinten alles wegzupoppen (schönes wort :D ).

      Aber wahrscheinlich bin ich von der Uni so auf diese Datenstrukturen geprägt, dass ich gar nicht mehr anders kann :whistling:
      Gemeint ist, dass beides möglich ist, der Code etwa gleich lang ist und man die tatsächliche Instruktions-Anszahl bei .net schlecht im Kopf abschätzen kann. ;)
      Der Unterschied ist auch schnell erklärt: eine Linked List ist nicht direkt mit nem Index adressierbar, da die Elemente nicht direkt hintereinander stehen, sondern ein Element zum Nächsten verweist. Eine ArrayList ist eine Mischung - man kann Elemente am Anfang und Ende einfach so rauslöschen -> Liste wird kürzer, jedoch verhalten sich die Daten in der Speicherverwaltung wie ein Array -> Löschen zwischendurch erfordert nachrücken, dafür direkt über Index adressierbar