using Avalonia; using Avalonia.Controls; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using EventBus; using SukiUI.Dialogs; using SukiUI.Toasts; using System; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Windows.Input; namespace ShakerApp.ViewModels; public abstract class ViewModelBase : ObservableObject where TModel : Shaker.Model.IModel { public virtual double Width => double.NaN; public virtual double Height => double.NaN; public virtual bool CanResize => true; [AllowNull] public Action CloseWindowAction { get; set; } public ISukiToastManager ToastManager { get; } = new SukiToastManager(); public ISukiDialogManager DialogManager { get; } = new SukiDialogManager(); [AllowNull] public virtual Type Content { get => content; set => SetProperty(ref content , value); } private string title = string.Empty; private bool saveIsEnabled= false; public bool SaveIsEnabled { get { return saveIsEnabled; } set {SetProperty(ref saveIsEnabled , value); } } [AllowNull] public DialogsViewModel Dialogs { get; } public virtual bool CanCancel { get; } = typeof(TModel).IsAnsiClass && !typeof(TModel).IsAbstract; public ViewModelBase() { Dialogs = new DialogsViewModel(DialogManager); if (typeof(TModel).IsAnsiClass && !typeof(TModel).IsAbstract) { Model = Activator.CreateInstance(); } } public ViewModelBase(TModel model) { UpDateModel(model); } public virtual void UpDateModel(TModel model) { Model = model; RefreshUI(); } public virtual void Init() { } protected void RefreshUI() { GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).ToList().ForEach(x => { OnPropertyChanged(x.Name); }); } private bool cansave = false; public virtual string OKContent => "Save"; public virtual string CancelContent =>"Cancel"; [AllowNull] private TModel model = default; public virtual TModel Model { get => model; set => SetProperty(ref model, value); } [return: NotNull] protected EventBus.EventBroker.EventData GetEvent() => (EventBroker.EventData)EventBroker.Instance.GetEvent(); [return: NotNull] protected EventBus.EventBroker.EventData GetEvent() => (EventBroker.EventData)EventBroker.Instance.GetEvent(); [return: NotNull] public EventBus.EventBroker.AnonymousEventData GetEvent([NotNull] string eventName) => (EventBroker.AnonymousEventData)EventBroker.Instance.GetEvent(eventName); [return: NotNull] public EventBus.EventBroker.AnonymousEventData GetEvent([NotNull] string eventName) => (EventBroker.AnonymousEventData)EventBroker.Instance.GetEvent(eventName); public ICommand SaveCommand => new RelayCommand(()=> { if (!cansave) return; Save(); cansave = false; }); public ICommand CancelCommand => new RelayCommand(Cancel); public virtual string Title { get => title; set =>SetProperty(ref title , value); } public bool ButtonVisibily { get => buttonVisibily; set =>SetProperty(ref buttonVisibily , value); } protected virtual void Save() { CommunicationViewModel.Intance.LocalCommunication?.GetEvent().Publish(this, Model); CommunicationViewModel.Intance.ServiceCommunication?.GetEvent().Publish(this, Model); lastModel = default; } [AllowNull] protected TModel lastModel; [AllowNull] private Type content; public virtual void InitData() { cansave = true; if (CanCancel) { lastModel = (TModel)Model.Clone(); SaveIsEnabled = false; } else { lastModel = default; } } protected virtual bool SkipProperty(string? propertyName) { return false; } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.PropertyName == nameof(Content) || e.PropertyName == nameof(Model) || e.PropertyName == nameof(ButtonVisibily) || e.PropertyName == nameof(SaveCommand) || e.PropertyName == nameof(Title) || e.PropertyName == nameof(SaveIsEnabled) || e.PropertyName == nameof(CancelCommand)) return; if (SkipProperty(e.PropertyName)) return; SaveIsEnabled = true; } private bool buttonVisibily = true; protected virtual void Cancel() { if (CanCancel && lastModel !=null) { UpDateModel(lastModel); lastModel = default; } } }