From 553a6fbaff87883f744bc1c20d4332ba03c3673f Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Tue, 14 May 2024 16:52:47 +0100 Subject: [PATCH] Fix some edge cases --- Toolkit.Avalonia/ContentTemplate.cs | 8 +- Toolkit.Foundation/ComponentBuilder.cs | 2 +- Toolkit.Foundation/DefaultHostBuilder.cs | 6 +- Toolkit.Foundation/Delete.cs | 10 +++ Toolkit.Foundation/DeleteEventArgs.cs | 3 + Toolkit.Foundation/Edit.cs | 10 +++ Toolkit.Foundation/EditEventArgs.cs | 3 + Toolkit.Foundation/IConfigurationSource.cs | 4 +- .../ObservableCollectionViewModel.cs | 77 +++++++++++-------- Toolkit.Foundation/ObservableViewModel.cs | 3 +- 10 files changed, 85 insertions(+), 41 deletions(-) create mode 100644 Toolkit.Foundation/Delete.cs create mode 100644 Toolkit.Foundation/DeleteEventArgs.cs create mode 100644 Toolkit.Foundation/Edit.cs create mode 100644 Toolkit.Foundation/EditEventArgs.cs diff --git a/Toolkit.Avalonia/ContentTemplate.cs b/Toolkit.Avalonia/ContentTemplate.cs index 2471d1e..499fc8c 100644 --- a/Toolkit.Avalonia/ContentTemplate.cs +++ b/Toolkit.Avalonia/ContentTemplate.cs @@ -50,10 +50,10 @@ public class ContentTemplate : await deactivated.OnDeactivated(); } - if (content is IDisposable disposable) - { - disposable.Dispose(); - } + //if (content is IDisposable disposable) + //{ + // disposable.Dispose(); + //} } } diff --git a/Toolkit.Foundation/ComponentBuilder.cs b/Toolkit.Foundation/ComponentBuilder.cs index bc3ffdf..425e3c9 100644 --- a/Toolkit.Foundation/ComponentBuilder.cs +++ b/Toolkit.Foundation/ComponentBuilder.cs @@ -29,7 +29,7 @@ public class ComponentBuilder : services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddSingleton(); services.AddTransient(); services.AddTransient(); diff --git a/Toolkit.Foundation/DefaultHostBuilder.cs b/Toolkit.Foundation/DefaultHostBuilder.cs index a65616e..5c731ac 100644 --- a/Toolkit.Foundation/DefaultHostBuilder.cs +++ b/Toolkit.Foundation/DefaultHostBuilder.cs @@ -23,9 +23,11 @@ public class DefaultHostBuilder : services.AddSingleton(); + services.AddSingleton(); + services.AddScoped(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); @@ -40,8 +42,6 @@ public class DefaultHostBuilder : services.AddScoped>(provider => new ProxyService(provider.GetRequiredService())); - services.AddScoped(); - services.AddTransient(); services.AddTransient(); diff --git a/Toolkit.Foundation/Delete.cs b/Toolkit.Foundation/Delete.cs new file mode 100644 index 0000000..a1a474c --- /dev/null +++ b/Toolkit.Foundation/Delete.cs @@ -0,0 +1,10 @@ +namespace Toolkit.Foundation; + +public record Delete +{ + public static DeleteEventArgs As(TValue value) => + new(value); + + public static DeleteEventArgs As() where TValue : new() => + new(new TValue()); +} \ No newline at end of file diff --git a/Toolkit.Foundation/DeleteEventArgs.cs b/Toolkit.Foundation/DeleteEventArgs.cs new file mode 100644 index 0000000..6901eff --- /dev/null +++ b/Toolkit.Foundation/DeleteEventArgs.cs @@ -0,0 +1,3 @@ +namespace Toolkit.Foundation; + +public record DeleteEventArgs(TValue Value); diff --git a/Toolkit.Foundation/Edit.cs b/Toolkit.Foundation/Edit.cs new file mode 100644 index 0000000..f39068d --- /dev/null +++ b/Toolkit.Foundation/Edit.cs @@ -0,0 +1,10 @@ +namespace Toolkit.Foundation; + +public record Edit +{ + public static EditEventArgs As(TValue value) => + new(value); + + public static EditEventArgs As() where TValue : new() => + new(new TValue()); +} diff --git a/Toolkit.Foundation/EditEventArgs.cs b/Toolkit.Foundation/EditEventArgs.cs new file mode 100644 index 0000000..9d1ff77 --- /dev/null +++ b/Toolkit.Foundation/EditEventArgs.cs @@ -0,0 +1,3 @@ +namespace Toolkit.Foundation; + +public record EditEventArgs(TValue Value); diff --git a/Toolkit.Foundation/IConfigurationSource.cs b/Toolkit.Foundation/IConfigurationSource.cs index 13d46f1..08da464 100644 --- a/Toolkit.Foundation/IConfigurationSource.cs +++ b/Toolkit.Foundation/IConfigurationSource.cs @@ -9,4 +9,6 @@ public interface IConfigurationSource void Set(TConfiguration value); void Set(object value); -} \ No newline at end of file +} + +public interface IRemovable : IDisposable; \ No newline at end of file diff --git a/Toolkit.Foundation/ObservableCollectionViewModel.cs b/Toolkit.Foundation/ObservableCollectionViewModel.cs index 3ce3f4d..3d5b971 100644 --- a/Toolkit.Foundation/ObservableCollectionViewModel.cs +++ b/Toolkit.Foundation/ObservableCollectionViewModel.cs @@ -29,11 +29,18 @@ public partial class ObservableCollectionViewModel : { private readonly ObservableCollection collection = []; + private bool clearing; + [ObservableProperty] private bool isInitialized; + [ObservableProperty] + private int selectedIndex = 0; + + private bool selfDisposing; + public ObservableCollectionViewModel(IServiceProvider provider, - IServiceFactory factory, + IServiceFactory factory, IMediator mediator, IPublisher publisher, ISubscriber subscriber, @@ -121,9 +128,6 @@ public partial class ObservableCollectionViewModel : } } - public virtual Task OnActivated() => - Task.CompletedTask; - public TViewModel Add() { TViewModel? item = Factory.Create(); @@ -196,12 +200,16 @@ public partial class ObservableCollectionViewModel : public void Clear() { - foreach (TViewModel item in collection) + clearing = true; + + foreach (TViewModel item in this.ToList()) { Disposer.Dispose(item); } ClearItems(); + + clearing = false; } public bool Contains(TViewModel item) => @@ -222,18 +230,28 @@ public partial class ObservableCollectionViewModel : return Task.CompletedTask; } - public virtual Task OnDeactivated() => - Task.CompletedTask; - - public virtual Task OnDeactivating() => - Task.CompletedTask; - public virtual void Dispose() { + selfDisposing = true; + GC.SuppressFinalize(this); Disposer.Dispose(this); } + public async Task Enumerate() + { + if (this.GetAttribute() is EnumerateAttribute attribute) + { + if (attribute.Mode == EnumerateMode.Reset) + { + Clear(); + } + + object? key = this.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key; + await Publisher.PublishUI(PrepareEnumeration(key)); + } + } + public IEnumerator GetEnumerator() => collection.GetEnumerator(); @@ -316,24 +334,6 @@ public partial class ObservableCollectionViewModel : await Enumerate(); } - - public async Task Enumerate() - { - if (this.GetAttribute() is EnumerateAttribute attribute) - { - if (attribute.Mode == EnumerateMode.Reset) - { - Clear(); - } - - object? key = this.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key; - await Publisher.PublishUI(PrepareEnumeration(key)); - } - } - - protected virtual IEnumerate PrepareEnumeration(object? key) => - new EnumerateEventArgs() with { Key = key }; - public void Insert(int index, TViewModel item) => InsertItem(index, item); @@ -360,6 +360,14 @@ public partial class ObservableCollectionViewModel : return true; } + public virtual Task OnActivated() => + Task.CompletedTask; + + public virtual Task OnDeactivated() => + Task.CompletedTask; + + public virtual Task OnDeactivating() => + Task.CompletedTask; public bool Remove(TViewModel item) { int index = collection.IndexOf(item); @@ -402,23 +410,30 @@ public partial class ObservableCollectionViewModel : } protected virtual void ClearItems() => - collection.Clear(); + collection.Clear(); protected virtual void InsertItem(int index, TViewModel item) { Disposer.Add(this, item); - Disposer.Add(item, item, Disposable.Create(() => + Disposer.Add(item, Disposable.Create(() => { if (item is IList collection) { collection.Clear(); } + + if (item is IRemovable && !clearing) + { + Remove(item); + } })); collection.Insert(index, item); } + protected virtual IEnumerate PrepareEnumeration(object? key) => + new EnumerateEventArgs() with { Key = key }; protected virtual void RemoveItem(int index) => collection.RemoveAt(index); diff --git a/Toolkit.Foundation/ObservableViewModel.cs b/Toolkit.Foundation/ObservableViewModel.cs index 9873f71..22a1c16 100644 --- a/Toolkit.Foundation/ObservableViewModel.cs +++ b/Toolkit.Foundation/ObservableViewModel.cs @@ -9,7 +9,8 @@ public partial class ObservableViewModel : IActivated, IDeactivating, IDeactivated, - IDeactivatable + IDeactivatable, + IDisposable { [ObservableProperty] private bool isInitialized;