Fix some edge cases

This commit is contained in:
TheXamlGuy
2024-05-14 16:52:47 +01:00
parent c310b3080c
commit 553a6fbaff
10 changed files with 85 additions and 41 deletions
+4 -4
View File
@@ -50,10 +50,10 @@ public class ContentTemplate :
await deactivated.OnDeactivated(); await deactivated.OnDeactivated();
} }
if (content is IDisposable disposable) //if (content is IDisposable disposable)
{ //{
disposable.Dispose(); // disposable.Dispose();
} //}
} }
} }
+1 -1
View File
@@ -29,7 +29,7 @@ public class ComponentBuilder :
services.AddScoped<SubscriptionCollection>(); services.AddScoped<SubscriptionCollection>();
services.AddScoped<ISubscriptionManager, SubscriptionManager>(); services.AddScoped<ISubscriptionManager, SubscriptionManager>();
services.AddScoped<IDisposer, Disposer>(); services.AddSingleton<IDisposer, Disposer>();
services.AddTransient<ISubscriber, Subscriber>(); services.AddTransient<ISubscriber, Subscriber>();
services.AddTransient<IPublisher, Publisher>(); services.AddTransient<IPublisher, Publisher>();
+3 -3
View File
@@ -23,9 +23,11 @@ public class DefaultHostBuilder :
services.AddSingleton<IComponentHostCollection, services.AddSingleton<IComponentHostCollection,
ComponentHostCollection>(); ComponentHostCollection>();
services.AddScoped<SubscriptionCollection>(); services.AddSingleton<IDisposer, Disposer>();
services.AddScoped<SubscriptionCollection>();
services.AddTransient<ISubscriptionManager, SubscriptionManager>(); services.AddTransient<ISubscriptionManager, SubscriptionManager>();
services.AddTransient<ISubscriber, Subscriber>(); services.AddTransient<ISubscriber, Subscriber>();
services.AddTransient<IPublisher, Publisher>(); services.AddTransient<IPublisher, Publisher>();
@@ -40,8 +42,6 @@ public class DefaultHostBuilder :
services.AddScoped<IProxyService<IComponentHostCollection>>(provider => services.AddScoped<IProxyService<IComponentHostCollection>>(provider =>
new ProxyService<IComponentHostCollection>(provider.GetRequiredService<IComponentHostCollection>())); new ProxyService<IComponentHostCollection>(provider.GetRequiredService<IComponentHostCollection>()));
services.AddScoped<IDisposer, Disposer>();
services.AddTransient<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>(); services.AddTransient<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>();
services.AddTransient<INavigationProvider, NavigationProvider>(); services.AddTransient<INavigationProvider, NavigationProvider>();
+10
View File
@@ -0,0 +1,10 @@
namespace Toolkit.Foundation;
public record Delete
{
public static DeleteEventArgs<TValue> As<TValue>(TValue value) =>
new(value);
public static DeleteEventArgs<TValue> As<TValue>() where TValue : new() =>
new(new TValue());
}
+3
View File
@@ -0,0 +1,3 @@
namespace Toolkit.Foundation;
public record DeleteEventArgs<TValue>(TValue Value);
+10
View File
@@ -0,0 +1,10 @@
namespace Toolkit.Foundation;
public record Edit
{
public static EditEventArgs<TValue> As<TValue>(TValue value) =>
new(value);
public static EditEventArgs<TValue> As<TValue>() where TValue : new() =>
new(new TValue());
}
+3
View File
@@ -0,0 +1,3 @@
namespace Toolkit.Foundation;
public record EditEventArgs<TValue>(TValue Value);
@@ -10,3 +10,5 @@ public interface IConfigurationSource<TConfiguration>
void Set(object value); void Set(object value);
} }
public interface IRemovable : IDisposable;
@@ -29,11 +29,18 @@ public partial class ObservableCollectionViewModel<TViewModel> :
{ {
private readonly ObservableCollection<TViewModel> collection = []; private readonly ObservableCollection<TViewModel> collection = [];
private bool clearing;
[ObservableProperty] [ObservableProperty]
private bool isInitialized; private bool isInitialized;
[ObservableProperty]
private int selectedIndex = 0;
private bool selfDisposing;
public ObservableCollectionViewModel(IServiceProvider provider, public ObservableCollectionViewModel(IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscriber subscriber, ISubscriber subscriber,
@@ -121,9 +128,6 @@ public partial class ObservableCollectionViewModel<TViewModel> :
} }
} }
public virtual Task OnActivated() =>
Task.CompletedTask;
public TViewModel Add() public TViewModel Add()
{ {
TViewModel? item = Factory.Create<TViewModel>(); TViewModel? item = Factory.Create<TViewModel>();
@@ -196,12 +200,16 @@ public partial class ObservableCollectionViewModel<TViewModel> :
public void Clear() public void Clear()
{ {
foreach (TViewModel item in collection) clearing = true;
foreach (TViewModel item in this.ToList())
{ {
Disposer.Dispose(item); Disposer.Dispose(item);
} }
ClearItems(); ClearItems();
clearing = false;
} }
public bool Contains(TViewModel item) => public bool Contains(TViewModel item) =>
@@ -222,18 +230,28 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return Task.CompletedTask; return Task.CompletedTask;
} }
public virtual Task OnDeactivated() =>
Task.CompletedTask;
public virtual Task OnDeactivating() =>
Task.CompletedTask;
public virtual void Dispose() public virtual void Dispose()
{ {
selfDisposing = true;
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
Disposer.Dispose(this); Disposer.Dispose(this);
} }
public async Task Enumerate()
{
if (this.GetAttribute<EnumerateAttribute>() 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<TViewModel> GetEnumerator() => public IEnumerator<TViewModel> GetEnumerator() =>
collection.GetEnumerator(); collection.GetEnumerator();
@@ -316,24 +334,6 @@ public partial class ObservableCollectionViewModel<TViewModel> :
await Enumerate(); await Enumerate();
} }
public async Task Enumerate()
{
if (this.GetAttribute<EnumerateAttribute>() 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<TViewModel>() with { Key = key };
public void Insert(int index, TViewModel item) => public void Insert(int index, TViewModel item) =>
InsertItem(index, item); InsertItem(index, item);
@@ -360,6 +360,14 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return true; 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) public bool Remove(TViewModel item)
{ {
int index = collection.IndexOf(item); int index = collection.IndexOf(item);
@@ -402,23 +410,30 @@ public partial class ObservableCollectionViewModel<TViewModel> :
} }
protected virtual void ClearItems() => protected virtual void ClearItems() =>
collection.Clear(); collection.Clear();
protected virtual void InsertItem(int index, protected virtual void InsertItem(int index,
TViewModel item) TViewModel item)
{ {
Disposer.Add(this, item); Disposer.Add(this, item);
Disposer.Add(item, item, Disposable.Create(() => Disposer.Add(item, Disposable.Create(() =>
{ {
if (item is IList collection) if (item is IList collection)
{ {
collection.Clear(); collection.Clear();
} }
if (item is IRemovable && !clearing)
{
Remove(item);
}
})); }));
collection.Insert(index, item); collection.Insert(index, item);
} }
protected virtual IEnumerate PrepareEnumeration(object? key) =>
new EnumerateEventArgs<TViewModel>() with { Key = key };
protected virtual void RemoveItem(int index) => protected virtual void RemoveItem(int index) =>
collection.RemoveAt(index); collection.RemoveAt(index);
+2 -1
View File
@@ -9,7 +9,8 @@ public partial class ObservableViewModel :
IActivated, IActivated,
IDeactivating, IDeactivating,
IDeactivated, IDeactivated,
IDeactivatable IDeactivatable,
IDisposable
{ {
[ObservableProperty] [ObservableProperty]
private bool isInitialized; private bool isInitialized;