Howto ask on unsafed Changes

General

A common task within your module might be the configuration. Saving and reading of the configuration can be done be following the guide here https://diegroupware.atlassian.net/wiki/spaces/ant2/pages/1442873345. But within the configuration pages (within the admin, client or antonyhub) the user can navigate away from your page, without saving the changes. In this case you should ask if the user wants to save the changes.

But as the AntonyView only provides a FrameworkElement (or WinForms) you cannot detect that the user navigates away. You also cannot use internal Events like Unload as this event is also called if the user changes the session. To solve the issue antony provides an extra interface for it. The IConfigurationViewModel

Tl;Dr;

  1. Let your ViewModel implement the IConfigurationViewModel Interface and implement it

  2. Pass the ViewModel in the AntonyView.FromWpfFrameworkElement as the 2nd parameter.

  3. Deploy

The IConfigurationViewModel Interface

This interface is specially designed for the given task and only has a few methods. The IsDirty Property is called by antony, if the user navigates away. If you return a dirty state, antony will ask the if the changes should be saved. If he decides to save, the Save method is called.

The OnClose Method will be called, if you provided a IConfigurationViewMOdel independent if your ViewModel ist dirty or not.

Create the AntonyView with IConfigurationViewModel

As antony cannot guess your ViewModel in a goo way, you need to pass it explicit to the AntonyView. Therefore you can use the static Method AntonyView.FromWpfFrameworkElement. In the second parameter you can pass the ViewModel. The snippet shows an AdministratorMenuNode as an example.

public class MyConfigurationAdminMenuNode: AdministratorMenuNode { public MyConfigurationAdminMenuNode(Func<MyConfigurationViewModel> createViewModel) { Identifier = "MyConfigurationName"; ParentIdentifier = "MyConfigurationParent"; DisplayName = "MyConfiguration"; ImageAsSvg = Resources.my_configuration; GenerateViewAsync = async reporter => { reporter.ReportStatus("Lade Daten"); BrowserTabConfigurationView view = new MyConfigurationView(); BrowserTabConfigurationViewModel viewModel = createViewModel.Invoke(); return AntonyView.FromWpfFrameworkElement(view, viewModel); }; } }

Implementing IConfigurationViewModel Example

If you are a module developer for antony you will get access to the assembly antony.groupware.wpf via our nuget feed. We recommend to use the IsDirtyTracker. To use it, simply create it within the constructor and pass the base object to track (this). The object needs to be a INotifyPropertyChanged to work correctly. The tracker will track all Properties with are annotated with the [DirtyTrack] attribute.

Members are not tracked by the IsDirtyTracker !

You can mark your ObservableCollection<T> with the DirtyTrack attribute. In this case the IsDirtyTracker will automatically track the Collection and every Element within the array automatically.

public class MyConfigurationViewModel : INotifyPropertyChanged, IConfigurationViewModel { public MyConfigurationViewModel() { StateTracker = new IsDirtyChangeTracker(this); } public IsDirtyChangeTracker StateTracker { get; set; } public DirtyState IsDirty => StateTracker.DirtyState; public void OnClose() => StateTracker.Dispose(); public void Save(IProgressReporter reporter) { DoSaveLogicHere(); StateTracker.IsDirty = false; // this will prevent double asking the user } #region Property string TestProperty private string _TestProperty; [DirtyTrack] public string TestProperty { get => _TestProperty; set { if (value == _TestProperty) return; _TestProperty = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TestProperty))); } } #endregion }

Conclusion

It is quite easy to track your ViewModel for changes and to give this information to antony. So it’s up to you to implement this feature for your customter.