using System; using System.Collections.Generic; using System.ComponentModel; 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 : ValidatableViewModelBase, 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) { } /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } /// /// Represents the base class for Artemis view models used to drive dialogs /// public abstract class DialogViewModelBase : ValidatableViewModelBase { /// /// Closes the dialog with the given /// /// The result of the dialog public void Close(TResult result) { CloseRequested?.Invoke(this, new DialogClosedEventArgs(result)); } internal event EventHandler>? CloseRequested; } /// /// Represents the base class for Artemis view models that are interested in validation and the activated event /// public abstract class ValidatableViewModelBase : ReactiveValidationObject, IActivatableViewModel { 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; } /// public ViewModelActivator Activator { get; } = new(); /// /// Raises the property changed event for the provided property. /// /// The event arguments containing the name of the property that changed. protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) { this.RaisePropertyChanged(args.PropertyName); } /// /// Raises the property changing event for the provided property. /// /// The event arguments containing the name of the property that is changing. protected virtual void OnPropertyChanging(PropertyChangingEventArgs args) { this.RaisePropertyChanging(args.PropertyName); } } /// /// 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 /// 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; } /// /// Raises the property changed event for the provided property. /// /// The event arguments containing the name of the property that changed. protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) { this.RaisePropertyChanged(args.PropertyName); } /// /// Raises the property changing event for the provided property. /// /// The event arguments containing the name of the property that is changing. protected virtual void OnPropertyChanging(PropertyChangingEventArgs args) { this.RaisePropertyChanging(args.PropertyName); } }