Implementieren Sie Undo / Redo-Vorgänge zum Hinzufügen / Löschen von ListView-Elementen
Ich habe zu viele Probleme beim Versuch, eine Undo / Redo-Operation in einem ListView-Steuerelement zu implementieren, nur um Elemente hinzuzufügen / zu entfernen.
Ich habe vor einiger Zeit eine relative Frage hier festgestelltErweitern Sie diese Klasse in einer Listenansicht auf Rückgängig / Wiederherstellen Wo ich angefangen habe mehrere Kopfgelder von 50, 100, 200 und 300 Punkten, insgesamt 650 Punkte ... aber niemand konnte mir wirklich helfen, dieses Problem in Wochen und Monaten abzuschließen.
Aber nach einiger Zeit in dieser Frage zeigte mir endlich ein Benutzer (@ThorstenC) eine mögliche Lösung und eine großartige Idee, der Code von ihm ist unvollständig, so dass der Code von ihm das ist, was ich zu realisieren / zu beenden versuche.
Das Problem ist, dass einfaches "Rückgängigmachen" gut funktioniert, aber wenn ich mehr als ein Mal versuche, eine Ausnahme auszulösen, kann das gleiche Element nicht erneut in die Listenansicht eingefügt werden. Außerdem hat der Code im Moment zum Beispiel mehr Probleme Ich kann einen Vorgang nicht rückgängig machen oder einen Vorgang rückgängig machen.
Ich brauche nur Hilfe, um einen funktionierenden Undo / Redo-Manager für das Hinzufügen / Entfernen von Listview-Elementen zu erstellen. Das ist alles. Ich habe den halben Teil des Codes geschrieben. Ich brauche Hilfe, um ihn zu beenden. Ich habe ein Durcheinander in meinem Kopf.
Hier ist ein einfaches WinForms-Quellprojekt in VS2012, das ich zum Testen des Undo-Managers hochgeladen habe:
http://elektrostudios.tk/UndoManager.zip
Hier ist ein Video, in dem die Fehler gezeigt werden, die beim Rückgängigmachen / Wiederherstellen auftreten:http://www.youtube.com/watch?v=MAzChURATpM
Hier ist die UndoManager-Klasse von @ThorstenC mit ein paar Retuschen:
Class ListView_UndoManager
Public Property Undostack As New Stack(Of ListView_Action)
Public Property Redostack As New Stack(Of ListView_Action)
Public Property IsDoingUndo As Boolean ' = False
Public Property IsDoingRedo As Boolean ' = False
Private action As ListView_Action = Nothing
''' <summary>
''' Undo the last action.
''' </summary>
''' <remarks></remarks>
Sub UndoLastAction()
If Undostack.Count = 0 Then Exit Sub ' Nothing to Undo.
action = Undostack.Pop ' Get the Action from Stack and remove it.
action.Operation.DynamicInvoke(action.data) ' Invoke the undo Action.
'Redostack = New Stack(Of ListView_Action)(Redostack)
'Redostack.Pop()
'Redostack = New Stack(Of ListView_Action)(Redostack)
End Sub
''' <summary>
''' Redo the last action.
''' </summary>
''' <remarks></remarks>
Sub RedoLastAction()
' If Redostack.Count = Undostack.Count Then Exit Sub
If Redostack.Count = 0 Then Exit Sub ' Nothing to Redo.
'Redostack = New Stack(Of ListView_Action)(Redostack) ' Reverse the Stack contents.
action = Redostack.Pop() ' Get the Action from Stack and remove it.
' action = Redostack.Peek()
action.Operation.DynamicInvoke(action.data) ' Invoke the redo Action.
'Redostack = New Stack(Of ListView_Action)(Redostack) ' Re-Reverse the Stack contents.
End Sub
End Class
Class ListView_Action
''' <summary>
''' Name the Undo / Redo Action
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property name As String
''' <summary>
''' Points to a method to excecute
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property Operation As [Delegate]
''' <summary>
''' Data Array for the method to excecute
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property data As Object()
End Class
Und hier ist der Rest des Codes, in dem ich versuche, das Hinzufügen / Löschen von Listenansichtselementen rückgängig zu machen / zu wiederholen:
Public Class Form1
Dim _undoManager As New ListView_UndoManager
Delegate Sub RemoveDelegate(item As ListViewItem)
Delegate Sub AddDelegate(item As ListViewItem)
Dim newItem As ListViewItem = Nothing
Sub AddItem(ByVal item As ListViewItem)
' // Crate an Undo Action
Dim u As New ListView_Action() With {.name = "Remove Item",
.Operation = New RemoveDelegate(AddressOf RemoveItem),
.data = New Object() {newItem}}
_undoManager.Undostack.Push(u)
ListView_Elektro1.AddItem(item)
End Sub
Sub RemoveItem(item As ListViewItem)
' // Create a Redo Action
Dim r As New ListView_Action() With {.name = "Add Item",
.Operation = New AddDelegate(AddressOf AddItem),
.data = New Object() {item}}
_undoManager.Redostack.Push(r)
' Remove the ListViewItem from ListView
ListView_Elektro1.RemoveItem(item)
End Sub
Private Sub Button_AddItem_Click(sender As Object, e As EventArgs) _
Handles Button_AddItem.Click
Dim index As String = CStr(ListView_Elektro1.Items.Count + 1)
newItem = New ListViewItem _
With {.Text = index}
newItem.SubItems.AddRange({"Hello " & index, "World " & index})
AddItem(newItem)
End Sub
Private Sub Button_RemoveItem_Click(sender As Object, e As EventArgs) _
Handles Button_RemoveItem.Click
newItem = ListView_Elektro1.Items.Cast(Of ListViewItem).Last
RemoveItem(newItem)
End Sub
Private Sub Button_Undo_Click(sender As Object, e As EventArgs) _
Handles Button_Undo.Click
' _undoManager.IsDoingUndo = True
_undoManager.UndoLastAction()
' _undoManager.IsDoingUndo = False
End Sub
Private Sub Button_Redo_Click(sender As Object, e As EventArgs) _
Handles Button_Redo.Click
'_undoManager.IsDoingRedo = True
_undoManager.RedoLastAction()
'_undoManager.IsDoingRedo = False
End Sub
Private Sub ListView_Elektro1_ItemAdded() _
Handles ListView_Elektro1.ItemAdded, _
ListView_Elektro1.ItemRemoved
Label_UndoCount_Value.Text = CStr(_undoManager.Undostack.Count)
Label_RedoCount_Value.Text = CStr(_undoManager.Redostack.Count)
End Sub
End Class