This is an open source package designed to define MVVM client application based on XAML (WinUI, UWP, WPF, or Xamarin)
Nuget | Github

Using UndoAsync in the scope you can undo every change applied in the scope to those properties registered with recording enabled:

RegisterProperty(vm => vm.FirstName).EnableRecording();
RegisterProperty(vm => vm.LastName);

Then you can apply UndoAsync() as follows:

(vm.FirstName, vm.LastName) = ("Unknown", "Unknown");
var scope = vm.BeginScope(sc =>
                vm.FirstName = "John";
                vm.LastName = "Wood";                                     
await scope.StartAsync();

var (first, last) = (vm.FirstName, vm.LastName) // ("John", "Wood")

await scope.UndoAsync();

(first, last) = (vm.FirstName, vm.LastName) // ("Unknown", "Wood") recording was enabled only in FirstName

Undo/Redo can also be enabled on collection property changes

An error has occurred. This application may no longer respond until reloaded. Reload 🗙