first off, since you are starting with a derived class, add these events to it:
' (your Item events still lack a Sender and Item to save a lot of work)
Public Event CheckChanged(ByVal sender As Object, _
ByVal lice As ListItemCheckChangedArgs)
Public Shadows Event BeforeLabelEdit(ByVal sender As Object, _
ByVal oldText As String)
BeforeLabelEdit is needed because the basic LV stored the old label text as Nothing
at the start and you'll want to change that to the .Text property to actually detect a change. Next, watching for Text changes will require you to do something different than you have for ItemAdded (no matter if it is universal or internal).
When Before...
fires, store a copy...a Watcher would compare _BeforeText to _AfterText (gotten from watching the normal AfterLabelEdit event) and if they are different, push the _BEforeText onto the stack.
CheckChanged
is a bit of a cheat. You can click on a LVItem Check directly and not fire any sort of Enter/GotFocus etc event. Which means a Watcher cannot get a _BeforeChecked
value. The native LV ItemChecked does fire and I just reorganize the args from it to pass what I need to the Watcher (via the above event). THe lice args:
Public Class ListItemCheckChangedArgs
Public Index As Integer ' index of item checked
Public OldValue As CheckState
Public NewValue As CheckState
Public Sub New(ByVal ndx As Integer, ByVal ov As CheckState, _
ByVal nv As CheckState)
Index = ndx
OldValue = ov
NewValue = nv
End Sub
End Class
The watcher then makes an UnDoAction object with OldValue as the data. Even without a watcher, this will help capture what you need.
The important part is the Undo class (an internal UM would be different):
Public Class ListViewEUndo
'... WHO this action applies to
Friend Ctl As ListViewEX
' a listview item, or string (Text) or bool (Check)
Friend UnDoData As Object
Friend LVActionType As LVEActionType = LVEActionType.None
' original index of items removed / index of item checked
Friend Index As Integer = -1
Public Sub New(ByVal _ctl As ListViewEX, ByVal _LvAType As LVEActionType, _
ByVal _data As Object)
Ctl = _ctl
LVActionType = _LvAType
UnDoData = _data
End Sub
...
LVEActionType
is just AddItem, RemoveItem etc (what this action type is)
You COULD design a base class and then inherit it for a TextUndo, CheckUndo and ItemUndo. It is a toss up whether that or the resulting short SELECT CASE statements are better. Finally, there are no DELEGATES because UndoManager class/helpers are going to do apply the changes themselves rather than export the work to the from or control (this ALSO helps to avoid Pushing actions caused by Undo/Redo actions!).
I'm not sure it is a full code example
, but may help with your issue depending on whether it is internal or not (internal needs almost no events - those are needed mainly to trigger Watcher actions - capture before value, capture/compare After value, respond to Add/RemoveItem etc).