using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using Artemis.UI.Shared.Events; using FluentAvalonia.UI.Controls; using JetBrains.Annotations; using ReactiveUI; using ReactiveUI.Validation.Helpers; namespace Artemis.UI.Shared; /// /// Represents the base class for Artemis view models /// public abstract class ContentDialogViewModelBase : ReactiveValidationObject, IActivatableViewModel, IDisposable { /// /// Gets the content dialog that hosts the view model /// public ContentDialog? ContentDialog { get; internal set; } /// /// Releases the unmanaged resources used by the object and optionally releases the managed resources. /// /// /// to release both managed and unmanaged resources; /// to release only unmanaged resources. /// protected virtual void Dispose(bool disposing) { } #region Implementation of IActivatableViewModel /// public ViewModelActivator Activator { get; } = new(); #endregion /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } /// /// Represents the base class for Artemis view models /// public abstract class ViewModelValidationBase : ReactiveValidationObject { private string? _displayName; /// /// Gets or sets the display name of the view model /// public string? DisplayName { get => _displayName; set => this.RaiseAndSetIfChanged(ref _displayName, value); } /// /// RaiseAndSetIfChanged fully implements a Setter for a read-write property on a ReactiveObject, using /// CallerMemberName to raise the notification and the ref to the backing field to set the property. /// /// The type of the return value. /// A Reference to the backing field for this property. /// The new value. /// /// The name of the property, usually automatically provided through the CallerMemberName /// attribute. /// /// The newly set value, normally discarded. [NotifyPropertyChangedInvocator] public TRet RaiseAndSetIfChanged(ref TRet backingField, TRet newValue, [CallerMemberName] string? propertyName = null) { if (propertyName is null) throw new ArgumentNullException(nameof(propertyName)); if (EqualityComparer.Default.Equals(backingField, newValue)) return newValue; this.RaisePropertyChanging(propertyName); backingField = newValue; this.RaisePropertyChanged(propertyName); return newValue; } } /// /// Represents the base class for Artemis view models /// public abstract class ViewModelBase : ReactiveObject { private string? _displayName; /// /// Gets or sets the display name of the view model /// public string? DisplayName { get => _displayName; set => RaiseAndSetIfChanged(ref _displayName, value); } /// /// RaiseAndSetIfChanged fully implements a Setter for a read-write property on a ReactiveObject, using /// CallerMemberName to raise the notification and the ref to the backing field to set the property. /// /// The type of the return value. /// A Reference to the backing field for this property. /// The new value. /// /// The name of the property, usually automatically provided through the CallerMemberName /// attribute. /// /// The newly set value, normally discarded. [NotifyPropertyChangedInvocator] public TRet RaiseAndSetIfChanged(ref TRet backingField, TRet newValue, [CallerMemberName] string? propertyName = null) { if (propertyName is null) throw new ArgumentNullException(nameof(propertyName)); if (EqualityComparer.Default.Equals(backingField, newValue)) return newValue; this.RaisePropertyChanging(propertyName); backingField = newValue; this.RaisePropertyChanged(propertyName); return newValue; } } /// /// Represents the base class for Artemis view models that are interested in the activated event /// public abstract class ActivatableViewModelBase : ViewModelBase, IActivatableViewModel { /// public ViewModelActivator Activator { get; } = new(); } /// /// Represents the base class for Artemis view models used to drive dialogs /// public abstract class DialogViewModelBase : ActivatableViewModelBase { /// /// Closes the dialog with the given /// /// The result of the dialog public void Close(TResult result) { CloseRequested?.Invoke(this, new DialogClosedEventArgs(result)); } /// /// Closes the dialog without a result /// public void Cancel() { CancelRequested?.Invoke(this, EventArgs.Empty); } internal event EventHandler>? CloseRequested; internal event EventHandler? CancelRequested; }