This commit is contained in:
TheXamlGuy
2024-05-18 20:40:12 +01:00
parent 85a14a8259
commit 1b60711ec4
9 changed files with 84 additions and 76 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ public partial class CommandViewModel(IServiceProvider provider,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer) : IDisposer disposer) :
ObservableViewModel(provider, factory, mediator, publisher, subscriber, disposer) Observable(provider, factory, mediator, publisher, subscriber, disposer)
{ {
public IRelayCommand InvokeCommand => public IRelayCommand InvokeCommand =>
new AsyncRelayCommand(InvokeAsync); new AsyncRelayCommand(InvokeAsync);
-2
View File
@@ -5,8 +5,6 @@ public record EnumerateEventArgs<TValue> :
{ {
public object? Key { get; init; } public object? Key { get; init; }
public EnumerateMode Mode { get; init; }
public static Enumerate<TValue, TOptions> With<TOptions>(TOptions options) where TOptions : class public static Enumerate<TValue, TOptions> With<TOptions>(TOptions options) where TOptions : class
{ {
return new Enumerate<TValue, TOptions>(options); return new Enumerate<TValue, TOptions>(options);
-2
View File
@@ -3,6 +3,4 @@
public interface IEnumerate public interface IEnumerate
{ {
object? Key { get; init; } object? Key { get; init; }
EnumerateMode Mode { get; init; }
} }
+10
View File
@@ -0,0 +1,10 @@
namespace Toolkit.Foundation;
public class Notify
{
public static NotifyEventArgs<TValue> As<TValue>(TValue value) =>
new(value);
public static NotifyEventArgs<TValue> As<TValue>() where TValue : new() =>
new(new TValue());
}
+3
View File
@@ -0,0 +1,3 @@
namespace Toolkit.Foundation;
public record NotifyEventArgs<TValue>(TValue Value);
@@ -2,7 +2,7 @@
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public partial class ObservableViewModel : public partial class Observable :
ObservableObject, ObservableObject,
IObservableViewModel, IObservableViewModel,
IInitializer, IInitializer,
@@ -20,7 +20,7 @@ public partial class ObservableViewModel :
[ObservableProperty] [ObservableProperty]
private bool isInitialized; private bool isInitialized;
public ObservableViewModel(IServiceProvider provider, public Observable(IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
@@ -81,25 +81,25 @@ public partial class ObservableViewModel :
} }
} }
public partial class ObservableViewModel<TValue>(IServiceProvider provider, public partial class Observable<TValue>(IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer) : ObservableViewModel(provider, factory, mediator, publisher, subscriber, disposer) IDisposer disposer) : Observable(provider, factory, mediator, publisher, subscriber, disposer)
where TValue : notnull where TValue : notnull
{ {
[ObservableProperty] [ObservableProperty]
private TValue? value; private TValue? value;
} }
public partial class ObservableViewModel<TKey, TValue>(IServiceProvider provider, public partial class Observable<TKey, TValue>(IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer, IDisposer disposer,
TValue? value = null) : ObservableViewModel(provider, factory, mediator, publisher, subscriber, disposer) TValue? value = null) : Observable(provider, factory, mediator, publisher, subscriber, disposer)
where TValue : class where TValue : class
{ {
[ObservableProperty] [ObservableProperty]
@@ -1,38 +1,37 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Collections; using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Reactive.Disposables; using System.Reactive.Disposables;
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public partial class ObservableCollectionViewModel<TViewModel> : public partial class ObservableCollection<TItem> :
ObservableObject, ObservableObject,
IObservableCollectionViewModel<TViewModel>, IObservableCollectionViewModel<TItem>,
IInitializer, IInitializer,
IActivated, IActivated,
IDeactivating, IDeactivating,
IDeactivated, IDeactivated,
IDeactivatable, IDeactivatable,
IList<TViewModel>, IList<TItem>,
IList, IList,
IReadOnlyList<TViewModel>, IReadOnlyList<TItem>,
INotifyCollectionChanged, INotifyCollectionChanged,
IServiceProviderRequired, IServiceProviderRequired,
IServiceFactoryRequired, IServiceFactoryRequired,
IMediatorRequired, IMediatorRequired,
IPublisherRequired, IPublisherRequired,
IDisposerRequired, IDisposerRequired,
INotificationHandler<RemoveEventArgs<TViewModel>>, INotificationHandler<RemoveEventArgs<TItem>>,
INotificationHandler<CreateEventArgs<TViewModel>>, INotificationHandler<CreateEventArgs<TItem>>,
INotificationHandler<InsertEventArgs<TViewModel>>, INotificationHandler<InsertEventArgs<TItem>>,
INotificationHandler<MoveEventArgs<TViewModel>>, INotificationHandler<MoveEventArgs<TItem>>,
INotificationHandler<ReplaceEventArgs<TViewModel>> INotificationHandler<ReplaceEventArgs<TItem>>
where TViewModel : where TItem :
notnull notnull
{ {
private readonly ObservableCollection<TViewModel> collection = []; private readonly System.Collections.ObjectModel.ObservableCollection<TItem> collection = [];
private bool clearing; private bool clearing;
@@ -42,7 +41,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
[ObservableProperty] [ObservableProperty]
private int selectedIndex = 0; private int selectedIndex = 0;
public ObservableCollectionViewModel(IServiceProvider provider, public ObservableCollection(IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
@@ -60,13 +59,13 @@ public partial class ObservableCollectionViewModel<TViewModel> :
collection.CollectionChanged += OnCollectionChanged; collection.CollectionChanged += OnCollectionChanged;
} }
public ObservableCollectionViewModel(IServiceProvider provider, public ObservableCollection(IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer, IDisposer disposer,
IEnumerable<TViewModel> items) IEnumerable<TItem> items)
{ {
Provider = provider; Provider = provider;
Factory = factory; Factory = factory;
@@ -92,7 +91,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
bool IList.IsFixedSize => false; bool IList.IsFixedSize => false;
bool ICollection<TViewModel>.IsReadOnly => false; bool ICollection<TItem>.IsReadOnly => false;
bool IList.IsReadOnly => false; bool IList.IsReadOnly => false;
@@ -106,7 +105,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
object ICollection.SyncRoot => this; object ICollection.SyncRoot => this;
public TViewModel this[int index] public TItem this[int index]
{ {
get => collection[index]; get => collection[index];
set => SetItem(index, value); set => SetItem(index, value);
@@ -117,11 +116,11 @@ public partial class ObservableCollectionViewModel<TViewModel> :
get => collection[index]; get => collection[index];
set set
{ {
TViewModel? item = default; TItem? item = default;
try try
{ {
item = (TViewModel)value!; item = (TItem)value!;
} }
catch (InvalidCastException) catch (InvalidCastException)
{ {
@@ -131,16 +130,16 @@ public partial class ObservableCollectionViewModel<TViewModel> :
} }
} }
public TViewModel Add() public TItem Add()
{ {
TViewModel? item = Factory.Create<TViewModel>(); TItem? item = Factory.Create<TItem>();
Add(item); Add(item);
return item; return item;
} }
public TViewModel Add<T>(params object?[] parameters) public TItem Add<T>(params object?[] parameters)
where T : TViewModel where T : TItem
{ {
T? item = Factory.Create<T>(parameters); T? item = Factory.Create<T>(parameters);
Add(item); Add(item);
@@ -148,9 +147,9 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return item; return item;
} }
public TViewModel Add<T>(bool scope = false) public TItem Add<T>(bool scope = false)
where T : where T :
TViewModel TItem
{ {
IServiceFactory? factory = null; IServiceFactory? factory = null;
if (scope) if (scope)
@@ -165,7 +164,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return item; return item;
} }
public void Add(TViewModel item) public void Add(TItem item)
{ {
int index = collection.Count; int index = collection.Count;
InsertItem(index, item); InsertItem(index, item);
@@ -174,16 +173,16 @@ public partial class ObservableCollectionViewModel<TViewModel> :
public void Add(object item) public void Add(object item)
{ {
int index = collection.Count; int index = collection.Count;
InsertItem(index, (TViewModel)item); InsertItem(index, (TItem)item);
} }
int IList.Add(object? value) int IList.Add(object? value)
{ {
TViewModel? item = default; TItem? item = default;
try try
{ {
item = (TViewModel)value!; item = (TItem)value!;
} }
catch (InvalidCastException) catch (InvalidCastException)
{ {
@@ -194,9 +193,9 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return Count - 1; return Count - 1;
} }
public void AddRange(IEnumerable<TViewModel> items) public void AddRange(IEnumerable<TItem> items)
{ {
foreach (TViewModel? item in items) foreach (TItem? item in items)
{ {
Add(item); Add(item);
} }
@@ -206,7 +205,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
{ {
clearing = true; clearing = true;
foreach (TViewModel item in this.ToList()) foreach (TItem item in this.ToList())
{ {
Disposer.Dispose(item); Disposer.Dispose(item);
} }
@@ -215,17 +214,17 @@ public partial class ObservableCollectionViewModel<TViewModel> :
clearing = false; clearing = false;
} }
public bool Contains(TViewModel item) => public bool Contains(TItem item) =>
collection.Contains(item); collection.Contains(item);
bool IList.Contains(object? value) => bool IList.Contains(object? value) =>
IsCompatibleObject(value) && Contains((TViewModel)value!); IsCompatibleObject(value) && Contains((TItem)value!);
public void CopyTo(TViewModel[] array, int index) => public void CopyTo(TItem[] array, int index) =>
collection.CopyTo(array, index); collection.CopyTo(array, index);
void ICollection.CopyTo(Array array, int index) => void ICollection.CopyTo(Array array, int index) =>
collection.CopyTo((TViewModel[])array, index); collection.CopyTo((TItem[])array, index);
public Task Deactivate() public Task Deactivate()
{ {
@@ -253,15 +252,15 @@ public partial class ObservableCollectionViewModel<TViewModel> :
} }
} }
public IEnumerator<TViewModel> GetEnumerator() => public IEnumerator<TItem> GetEnumerator() =>
collection.GetEnumerator(); collection.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => IEnumerator IEnumerable.GetEnumerator() =>
((IEnumerable)collection).GetEnumerator(); ((IEnumerable)collection).GetEnumerator();
public Task Handle(RemoveEventArgs<TViewModel> args) public Task Handle(RemoveEventArgs<TItem> args)
{ {
foreach (TViewModel item in this.ToList()) foreach (TItem item in this.ToList())
{ {
if (args.Value is not null && args.Value.Equals(item)) if (args.Value is not null && args.Value.Equals(item))
{ {
@@ -272,9 +271,9 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task Handle(CreateEventArgs<TViewModel> args) public Task Handle(CreateEventArgs<TItem> args)
{ {
if (args.Value is TViewModel item) if (args.Value is TItem item)
{ {
Add(item); Add(item);
} }
@@ -282,9 +281,9 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task Handle(InsertEventArgs<TViewModel> args) public Task Handle(InsertEventArgs<TItem> args)
{ {
if (args.Value is TViewModel item) if (args.Value is TItem item)
{ {
Insert(args.Index, item); Insert(args.Index, item);
} }
@@ -292,9 +291,9 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task Handle(MoveEventArgs<TViewModel> args) public Task Handle(MoveEventArgs<TItem> args)
{ {
if (args.Value is TViewModel item) if (args.Value is TItem item)
{ {
Move(args.Index, item); Move(args.Index, item);
} }
@@ -302,9 +301,9 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task Handle(ReplaceEventArgs<TViewModel> args) public Task Handle(ReplaceEventArgs<TItem> args)
{ {
if (args.Value is TViewModel item) if (args.Value is TItem item)
{ {
Replace(args.Index, item); Replace(args.Index, item);
} }
@@ -312,12 +311,12 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return Task.CompletedTask; return Task.CompletedTask;
} }
public int IndexOf(TViewModel item) => public int IndexOf(TItem item) =>
collection.IndexOf(item); collection.IndexOf(item);
int IList.IndexOf(object? value) => int IList.IndexOf(object? value) =>
IsCompatibleObject(value) ? IsCompatibleObject(value) ?
IndexOf((TViewModel)value!) : -1; IndexOf((TItem)value!) : -1;
public Task Initialize() public Task Initialize()
{ {
@@ -332,19 +331,19 @@ public partial class ObservableCollectionViewModel<TViewModel> :
return Task.CompletedTask; return Task.CompletedTask;
} }
public void Insert(int index, TViewModel item) => public void Insert(int index, TItem item) =>
InsertItem(index, item); InsertItem(index, item);
void IList.Insert(int index, void IList.Insert(int index,
object? value) object? value)
{ {
if (value is TViewModel item) if (value is TItem item)
{ {
Insert(index, item); Insert(index, item);
} }
} }
public bool Move(int index, TViewModel item) public bool Move(int index, TItem item)
{ {
int oldIndex = collection.IndexOf(item); int oldIndex = collection.IndexOf(item);
if (oldIndex < 0) if (oldIndex < 0)
@@ -367,7 +366,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
public virtual Task OnDeactivating() => public virtual Task OnDeactivating() =>
Task.CompletedTask; Task.CompletedTask;
public bool Remove(TViewModel item) public bool Remove(TItem item)
{ {
int index = collection.IndexOf(item); int index = collection.IndexOf(item);
if (index < 0) if (index < 0)
@@ -385,7 +384,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
{ {
if (IsCompatibleObject(value)) if (IsCompatibleObject(value))
{ {
Remove((TViewModel)value!); Remove((TItem)value!);
} }
} }
@@ -393,7 +392,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
RemoveItem(index); RemoveItem(index);
public bool Replace(int index, public bool Replace(int index,
TViewModel item) TItem item)
{ {
if (index <= Count - 1) if (index <= Count - 1)
{ {
@@ -412,7 +411,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
collection.Clear(); collection.Clear();
protected virtual void InsertItem(int index, protected virtual void InsertItem(int index,
TViewModel item) TItem item)
{ {
Disposer.Add(this, item); Disposer.Add(this, item);
Disposer.Add(item, Disposable.Create(() => Disposer.Add(item, Disposable.Create(() =>
@@ -432,16 +431,16 @@ public partial class ObservableCollectionViewModel<TViewModel> :
} }
protected virtual IEnumerate PrepareEnumeration(object? key) => protected virtual IEnumerate PrepareEnumeration(object? key) =>
new EnumerateEventArgs<TViewModel>() with { Key = key }; new EnumerateEventArgs<TItem>() with { Key = key };
protected virtual void RemoveItem(int index) => protected virtual void RemoveItem(int index) =>
collection.RemoveAt(index); collection.RemoveAt(index);
protected virtual void SetItem(int index, TViewModel item) => protected virtual void SetItem(int index, TItem item) =>
collection[index] = item; collection[index] = item;
private static bool IsCompatibleObject(object? value) => private static bool IsCompatibleObject(object? value) =>
(value is TViewModel) || (value == null && default(TViewModel) == null); (value is TItem) || (value == null && default(TItem) == null);
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args) => private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args) =>
CollectionChanged?.Invoke(this, args); CollectionChanged?.Invoke(this, args);
@@ -460,21 +459,21 @@ public partial class ObservableCollectionViewModel<TViewModel> :
} }
} }
public partial class ObservableCollectionViewModel<TValue, TViewModel>(IServiceProvider provider, public partial class ObservableCollection<TValue, TViewModel>(IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, IDisposer disposer) : ObservableCollectionViewModel<TViewModel>(provider, factory, mediator, publisher, subscriber, disposer) ISubscription subscriber, IDisposer disposer) : ObservableCollection<TViewModel>(provider, factory, mediator, publisher, subscriber, disposer)
where TViewModel : notnull where TViewModel : notnull
{ {
[ObservableProperty] [ObservableProperty]
private TValue? value; private TValue? value;
} }
public class ObservableCollectionViewModel(IServiceProvider provider, public class ObservableCollection(IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer) : IDisposer disposer) :
ObservableCollectionViewModel<IDisposable>(provider, factory, mediator, publisher, subscriber, disposer); ObservableCollection<IDisposable>(provider, factory, mediator, publisher, subscriber, disposer);
+1 -1
View File
@@ -8,7 +8,7 @@ public partial class ValueViewModel<TValue>(IServiceProvider provider,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer) : IDisposer disposer) :
ObservableViewModel(provider, factory, mediator, publisher, subscriber, disposer) Observable(provider, factory, mediator, publisher, subscriber, disposer)
{ {
[ObservableProperty] [ObservableProperty]
private TValue? value; private TValue? value;