diff --git a/StabilityMatrix.Avalonia/Models/ViewModelState.cs b/StabilityMatrix.Avalonia/Models/ViewModelState.cs new file mode 100644 index 00000000..d195a7a6 --- /dev/null +++ b/StabilityMatrix.Avalonia/Models/ViewModelState.cs @@ -0,0 +1,15 @@ +using System; + +namespace StabilityMatrix.Avalonia.Models; + +/// +/// +/// +[Flags] +public enum ViewModelState : uint +{ + /// + /// View Model has been initially loaded + /// + InitialLoaded = 1 << 0, +} diff --git a/StabilityMatrix.Avalonia/ViewModels/Base/ViewModelBase.cs b/StabilityMatrix.Avalonia/ViewModels/Base/ViewModelBase.cs index 0cce47ba..0d9899cc 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Base/ViewModelBase.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Base/ViewModelBase.cs @@ -2,14 +2,18 @@ using System.Threading.Tasks; using AsyncAwaitBestPractices; using CommunityToolkit.Mvvm.ComponentModel; +using JetBrains.Annotations; using StabilityMatrix.Avalonia.Models; namespace StabilityMatrix.Avalonia.ViewModels.Base; public class ViewModelBase : ObservableValidator, IRemovableListItem { + [PublicAPI] + protected ViewModelState ViewModelState { get; private set; } + private WeakEventManager? parentListRemoveRequestedEventManager; - + public event EventHandler ParentListRemoveRequested { add @@ -20,24 +24,51 @@ public class ViewModelBase : ObservableValidator, IRemovableListItem remove => parentListRemoveRequestedEventManager?.RemoveEventHandler(value); } - protected void RemoveFromParentList() => parentListRemoveRequestedEventManager?.RaiseEvent( - this, EventArgs.Empty, nameof(ParentListRemoveRequested)); - + protected void RemoveFromParentList() => + parentListRemoveRequestedEventManager?.RaiseEvent( + this, + EventArgs.Empty, + nameof(ParentListRemoveRequested) + ); + + /// + /// Called when the view's LoadedEvent is fired. + /// public virtual void OnLoaded() { - + if (!ViewModelState.HasFlag(ViewModelState.InitialLoaded)) + { + ViewModelState |= ViewModelState.InitialLoaded; + OnInitialLoaded(); + } } + /// + /// Called the first time the view's LoadedEvent is fired. + /// Sets the flag. + /// + protected virtual void OnInitialLoaded() { } + + /// + /// Called asynchronously when the view's LoadedEvent is fired. + /// Runs on the UI thread via Dispatcher.UIThread.InvokeAsync. + /// The view loading will not wait for this to complete. + /// public virtual Task OnLoadedAsync() { return Task.CompletedTask; } - - public virtual void OnUnloaded() - { - - } - + + /// + /// Called when the view's UnloadedEvent is fired. + /// + public virtual void OnUnloaded() { } + + /// + /// Called asynchronously when the view's UnloadedEvent is fired. + /// Runs on the UI thread via Dispatcher.UIThread.InvokeAsync. + /// The view loading will not wait for this to complete. + /// public virtual Task OnUnloadedAsync() { return Task.CompletedTask;