rewrite ObservableCollectionViewModel
This commit is contained in:
@@ -1,22 +1,31 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace Hyperbar;
|
||||
|
||||
|
||||
public class ObservableCollectionViewModel<TItem> :
|
||||
ObservableCollection<TItem>,
|
||||
public partial class ObservableCollectionViewModel<TItem> :
|
||||
ObservableObject,
|
||||
IList<TItem>,
|
||||
IList,
|
||||
IReadOnlyList<TItem>,
|
||||
INotifyCollectionChanged,
|
||||
INotificationHandler<CollectionChanged<IEnumerable<TItem>>>
|
||||
{
|
||||
private readonly IServiceFactory serviceFactory;
|
||||
public ObservableCollection<TItem> collection = [];
|
||||
private readonly SynchronizationContext? context;
|
||||
private readonly IServiceFactory serviceFactory;
|
||||
|
||||
public ObservableCollectionViewModel(IServiceFactory serviceFactory,
|
||||
public ObservableCollectionViewModel(IServiceFactory serviceFactory,
|
||||
IMediator mediator)
|
||||
{
|
||||
context = SynchronizationContext.Current;
|
||||
|
||||
this.serviceFactory = serviceFactory;
|
||||
mediator.Subscribe(this);
|
||||
|
||||
collection.CollectionChanged += OnCollectionChanged;
|
||||
}
|
||||
|
||||
public ObservableCollectionViewModel(IServiceFactory serviceFactory,
|
||||
@@ -28,9 +37,56 @@ public class ObservableCollectionViewModel<TItem> :
|
||||
this.serviceFactory = serviceFactory;
|
||||
mediator.Subscribe(this);
|
||||
|
||||
collection.CollectionChanged += OnCollectionChanged;
|
||||
|
||||
AddRange(items);
|
||||
}
|
||||
|
||||
public event NotifyCollectionChangedEventHandler? CollectionChanged;
|
||||
|
||||
public int Count => collection.Count;
|
||||
|
||||
bool IList.IsFixedSize => false;
|
||||
|
||||
bool ICollection<TItem>.IsReadOnly => false;
|
||||
|
||||
bool IList.IsReadOnly => false;
|
||||
|
||||
bool ICollection.IsSynchronized => false;
|
||||
|
||||
object ICollection.SyncRoot => this;
|
||||
|
||||
protected IList<TItem> Items => collection;
|
||||
|
||||
public TItem this[int index]
|
||||
{
|
||||
get => collection[index];
|
||||
set
|
||||
{
|
||||
SetItem(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
object? IList.this[int index]
|
||||
{
|
||||
get => collection[index];
|
||||
set
|
||||
{
|
||||
TItem? item = default;
|
||||
|
||||
try
|
||||
{
|
||||
item = (TItem)value!;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
this[index] = item!;
|
||||
}
|
||||
}
|
||||
|
||||
public TItem Add()
|
||||
{
|
||||
TItem? item = serviceFactory.Create<TItem>();
|
||||
@@ -58,6 +114,29 @@ public class ObservableCollectionViewModel<TItem> :
|
||||
return item;
|
||||
}
|
||||
|
||||
public void Add(TItem item)
|
||||
{
|
||||
int index = collection.Count;
|
||||
InsertItem(index, item);
|
||||
}
|
||||
|
||||
int IList.Add(object? value)
|
||||
{
|
||||
TItem? item = default;
|
||||
|
||||
try
|
||||
{
|
||||
item = (TItem)value!;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Add(item!);
|
||||
return Count - 1;
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<TItem> items)
|
||||
{
|
||||
foreach (TItem? item in items)
|
||||
@@ -65,8 +144,21 @@ public class ObservableCollectionViewModel<TItem> :
|
||||
context?.Post(state => Add(item), null);
|
||||
}
|
||||
}
|
||||
public void Clear() => ClearItems();
|
||||
|
||||
public ValueTask Handle(CollectionChanged<IEnumerable<TItem>> notification,
|
||||
public bool Contains(TItem item) => collection.Contains(item);
|
||||
|
||||
bool IList.Contains(object? value) => IsCompatibleObject(value) && Contains((TItem)value!);
|
||||
|
||||
public void CopyTo(TItem[] array, int index) => collection.CopyTo(array, index);
|
||||
|
||||
void ICollection.CopyTo(Array array, int index) => collection.CopyTo((TItem[])array, index);
|
||||
|
||||
public IEnumerator<TItem> GetEnumerator() => collection.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)collection).GetEnumerator();
|
||||
|
||||
public ValueTask Handle(CollectionChanged<IEnumerable<TItem>> notification,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
context?.Post(state => Clear(), null);
|
||||
@@ -74,6 +166,55 @@ public class ObservableCollectionViewModel<TItem> :
|
||||
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public int IndexOf(TItem item) => collection.IndexOf(item);
|
||||
|
||||
int IList.IndexOf(object? value) => IsCompatibleObject(value) ? IndexOf((TItem)value!) : -1;
|
||||
|
||||
public void Insert(int index, TItem item) => InsertItem(index, item);
|
||||
|
||||
void IList.Insert(int index, object? value)
|
||||
{
|
||||
if (value is TItem item)
|
||||
{
|
||||
Insert(index, item);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove(TItem item)
|
||||
{
|
||||
int index = collection.IndexOf(item);
|
||||
if (index < 0) return false;
|
||||
RemoveItem(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IList.Remove(object? value)
|
||||
{
|
||||
if (IsCompatibleObject(value))
|
||||
{
|
||||
Remove((TItem)value!);
|
||||
}
|
||||
}
|
||||
public void RemoveAt(int index) => RemoveItem(index);
|
||||
|
||||
protected virtual void ClearItems() => collection.Clear();
|
||||
|
||||
protected virtual void InsertItem(int index, TItem value)
|
||||
{
|
||||
if (value is TItem item)
|
||||
{
|
||||
collection.Insert(index, item);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void RemoveItem(int index) => collection.RemoveAt(index);
|
||||
|
||||
protected virtual void SetItem(int index, TItem item) => collection[index] = item;
|
||||
|
||||
private static bool IsCompatibleObject(object? value) => (value is TItem) || (value == null && default(TItem) == null);
|
||||
|
||||
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args) => CollectionChanged?.Invoke(this, args);
|
||||
}
|
||||
|
||||
public class ObservableCollectionViewModel(IServiceFactory serviceFactory, IMediator mediator) :
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Hyperbar;
|
||||
|
||||
public class WidgetContainerViewModel(ITemplateFactory templateFactory,
|
||||
public partial class WidgetContainerViewModel(ITemplateFactory templateFactory,
|
||||
IServiceFactory serviceFactory,
|
||||
IMediator mediator,
|
||||
IEnumerable<IWidgetViewModel> items) :
|
||||
IEnumerable<IWidgetViewModel> items,
|
||||
bool alternate) :
|
||||
ObservableCollectionViewModel<IWidgetViewModel>(serviceFactory, mediator, items),
|
||||
ITemplatedViewModel
|
||||
{
|
||||
[ObservableProperty]
|
||||
private bool alternate = alternate;
|
||||
|
||||
public ITemplateFactory TemplateFactory => templateFactory;
|
||||
}
|
||||
Reference in New Issue
Block a user