using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows.Input; namespace CVRManager.ViewModels; public abstract class ObservableObject : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; protected bool Set(ref T field, T value, [CallerMemberName] string? name = null) { if (EqualityComparer.Default.Equals(field, value)) return false; field = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); return true; } protected void Raise([CallerMemberName] string? name = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } public class RelayCommand : ICommand { readonly Func run; public RelayCommand(Func run) => this.run = run; public RelayCommand(Action run) => this.run = () => { run(); return Task.CompletedTask; }; public event EventHandler? CanExecuteChanged { add { } remove { } } public bool CanExecute(object? parameter) => true; public async void Execute(object? parameter) => await run(); }