Implement Undo/Redo operations for Adding/Deleting ListView Items

前端 未结 2 494
伪装坚强ぢ
伪装坚强ぢ 2021-01-23 18:26

I have too much problems trying to implement an Undo/Redo operation in a ListView Control, just to add/remove items.

I realized time ago a relative question here Extend

相关标签:
2条回答
  • 2021-01-23 18:44

    You might also want to check out this Undo/Redo Framework written in VB.NET

    http://www.codeproject.com/Articles/43436/Undo-Redo-Framework

    Its designed for the following type of controls (but should also work with custom controls for the most part)

    • TextBox
    • ComboBox
    • DateTimePicker
    • NumericUpDown
    • MaskedTextBox
    • ListBox (single and multi-select)
    • CheckBox
    • RadioButton
    • MonthCalendar
    • ListView (Label text changes)
    0 讨论(0)
  • 2021-01-23 18:52

    "El URL requerido no fue encontrado en este servidor." So I am only pretty sure this is it:

    action = Redostack.Peek() ' Get the Action from Stack and remove it.
    

    No, you are looking at it without getting it from the stack. Both the original and a quick rework of it I did use:

    action = Redostack.Pop() 
    

    Since you are storing actual LV Items in the stack to post back to the LV, the second time you press it your are looking at and trying to restore one already in the LV.

    Since the most of the original "Commands" saved the Undo/ReDo data as object why didnt you just expose an AddLVUndoItem(item) on UnDoReDoManager to use the existing code to integrate LV actions with the other controls? The problem it had was that there is no LVItemAdded event to automatically grab those things. One problem using this as a user-controlled feature along with the other one is that you now have 2 stacks one skips over LV, the other only does LV. The user could empty the other stack trying to get to LV undo actions.

    Also, adding an item is falling into the UnDo bucket, but not RemoveItem and vice-versa for RemoveItem (cant Undo RemoveItem). In the original Undo automatically added the command to the ReDo stack. It is in the title and the old request but not the code.

    Edit This is wrong:

    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}}   ' wrong!
    
        _undoManager.Redostack.Push(r)
    
        ' Remove the ListViewItem from ListView
        ListView_Elektro1.RemoveItem(item)
    End Sub
    

    You dont create a new LVI for the undoStack, use the one passed which is the one removed (recall I had to change the syntax for my VS ver):

    Sub RemoveItem(ByVal item As ListViewItem)
    
        ' // Create a Redo Action
        Dim r As New ListView_Action()
        With r
            .name = "Add Item"
            .Operation = New AddDelegate(AddressOf AddItem)
            .data = item           ' use the one passed!!!
        End With
    
        _undoManager.Redostack.Push(r)
    
        ' Remove the ListViewItem from ListView
        LVE.RemoveItem(item)
        _undoManager.ShowStacks()
    
    End Sub
    

    As a result, your ReDo wasnt caching any of the UnDo actions. It only looked like it was due to the artificial test data.

    0 讨论(0)
提交回复
热议问题