Zaimplementuj operacje cofania / ponawiania w celu dodawania / usuwania elementów listyView

Mam za dużo problemów podczas próby wykonania operacji Cofnij / Ponów w Kontrolce ListView, tylko po to, by dodawać / usuwać elementy.

Czas temu zdałem sobie sprawę z względnego pytania tutajRozszerz tę klasę na cofnij / ponów w widoku listy gdzie rozpocząłem wiele nagród o wartości 50, 100, 200 i 300 punktów, łącznie 650 punktów ... ale żadne ciało nie mogło mi pomóc w sfinalizowaniu tego problemu w ciągu tygodni i miesięcy.

Ale po pewnym czasie w tym pytaniu użytkownik (@ThorstenC) pokazał mi możliwe rozwiązanie i świetny pomysł, jego kod jest niekompletny, więc jego kod jest tym, co próbuję zrealizować / zakończyć.

Problem jest prosty „Cofnij” działa dobrze, ale gdy próbuję powtórzyć więcej niż 1 raz, zgłasza wyjątek, że nie może ponownie dodać tego samego elementu w widoku listy, również kod ma więcej problemów, na przykład w tej chwili ja Nie mogę powtórzyć operacji cofania lub cofnąć operacji ponownego wykonania.

Po prostu potrzebuję pomocy, aby stworzyć działającego menedżera cofania / ponawiania dla elementu Listview, dodając / usuwając, to wszystko, napisałem połowę kodu, potrzebuję pomocy, aby go ukończyć.

Oto prosty projekt źródłowy WinForm w VS2012, który przesłałem, aby sprawdzić, czy menedżer cofania nie działa:

http://elektrostudios.tk/UndoManager.zip

Oto film pokazujący błędy, które próbuję cofnąć / powtórzyć:http://www.youtube.com/watch?v=MAzChURATpM

Oto klasa UndoManager @ThorstenC z małymi retuszami:

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

A oto reszta kodu, w którym próbuję cofnąć / powtórzyć Dodawanie / usuwanie elementów widoku listy:

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

questionAnswers(2)

yourAnswerToTheQuestion