Undo/Redo

Oct 13, 2009 at 3:54 PM

Have you considered undo/redo functionality for capturing property changes. This would be a great feature to round out the needs in developing a solid LOB application. The way I would like to see this implemented is to have a ThreadStatic variable that is a "transaction" (or a nested transaction) where property changes get recorded (if the transaction is not null) as "commands" that can be undone and redone. Of course, as always, special challenges exist in handling collection changes. And, possible a way to define a property as not undoable.

It seems like you're already hooked into all the right places.

Wish I was just a little better at reflection and other advanced C# programming and I would implement myself. Maybe I will try anyway... but, thought I would ask first. :)

Thanks!

- Brian

Coordinator
Oct 13, 2009 at 6:09 PM

I attempted just such a mechanism in a prior incarnation of the library (the C++ version I originally started with). It didn't work out so well.

The first thing you need to do is put boundaries on user intent. The program might make several changes in response to a single user action. The user expects all of those changes to get rolled back together.

The next thing is to store prior state and next state. This is simple with atomic value types (like int). But it's more difficult with collections. And it's almost impossible to get reference types correct without having more information. Is it a reference to something else in the document, or do I own it, for example.

Third, there's a difference between document data and navigation. If the user changes the data model, you want that to undo. But if they just switch to a different point-of-view, you don't. The library would have to be told the difference.

And finally there are all the side-effects. There's no telling what your application might need to do when the user makes a change. Are the side-effects captured in the undo itself, or do they need to be recomputed? It depends.

So instead, I just decided to make Update Controls focus on one thing: dependency discovery. It can do this well, but it will fail if it tries to take on too much.

 

BTW, Update Controls does not use reflection, other than in the places it integrates with WPF data binding. It doesn't care what your independent field is named, what its data type is, or what value you're storing in it. It only cares about when you set it and when you get it.