INotifyCollectionChangedSynchronizedViewList -> NotifyCollectionChangedSynchronizedViewList

This commit is contained in:
neuecc 2024-10-16 13:50:24 +09:00
parent 8afb3fb100
commit 7987d75b8d
9 changed files with 456 additions and 648 deletions

View File

@ -17,7 +17,7 @@ var list = new ObservableList<Person>()
var view = list.CreateWritableView(x => x.Name); var view = list.CreateWritableView(x => x.Name);
view.AttachFilter(x => x.Age >= 20); view.AttachFilter(x => x.Age >= 20);
IList<string?> bindable = view.ToWritableNotifyCollectionChanged((string? newView, Person original, ref bool setValue) => var bindable = view.ToWritableNotifyCollectionChanged((string? newView, Person original, ref bool setValue) =>
{ {
if (setValue) if (setValue)
{ {

View File

@ -47,8 +47,8 @@ namespace ObservableCollections
void AttachFilter(ISynchronizedViewFilter<T> filter); void AttachFilter(ISynchronizedViewFilter<T> filter);
void ResetFilter(); void ResetFilter();
ISynchronizedViewList<TView> ToViewList(); ISynchronizedViewList<TView> ToViewList();
INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(); NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged();
INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher); NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher);
} }
public interface IWritableSynchronizedView<T, TView> : ISynchronizedView<T, TView> public interface IWritableSynchronizedView<T, TView> : ISynchronizedView<T, TView>
@ -58,9 +58,9 @@ namespace ObservableCollections
void SetToSourceCollection(int index, T value); void SetToSourceCollection(int index, T value);
void AddToSourceCollection(T value); void AddToSourceCollection(T value);
IWritableSynchronizedViewList<TView> ToWritableViewList(WritableViewChangedEventHandler<T, TView> converter); IWritableSynchronizedViewList<TView> ToWritableViewList(WritableViewChangedEventHandler<T, TView> converter);
INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter); NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter);
INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher); NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher);
INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter, ICollectionEventDispatcher? collectionEventDispatcher); NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter, ICollectionEventDispatcher? collectionEventDispatcher);
} }
public interface ISynchronizedViewList<out TView> : IReadOnlyList<TView>, IDisposable public interface ISynchronizedViewList<out TView> : IReadOnlyList<TView>, IDisposable
@ -72,10 +72,97 @@ namespace ObservableCollections
new TView this[int index] { get; set; } new TView this[int index] { get; set; }
} }
// only for compatibility, use NotifyCollectionChangedSynchronizedViewList insetad.
// [Obsolete] in future
public interface INotifyCollectionChangedSynchronizedViewList<TView> : IList<TView>, IList, ISynchronizedViewList<TView>, INotifyCollectionChanged, INotifyPropertyChanged public interface INotifyCollectionChangedSynchronizedViewList<TView> : IList<TView>, IList, ISynchronizedViewList<TView>, INotifyCollectionChanged, INotifyPropertyChanged
{ {
} }
// IColleciton<T>.Count and ICollection.Count will be ambigious so use abstract class instead of interface
public abstract class NotifyCollectionChangedSynchronizedViewList<TView> :
INotifyCollectionChangedSynchronizedViewList<TView>,
IWritableSynchronizedViewList<TView>,
IList<TView>,
IList
{
protected readonly object gate = new object();
public abstract TView this[int index] { get; set; }
object? IList.this[int index]
{
get
{
return this[index];
}
set => ((IList<TView>)this)[index] = (TView)value!;
}
public abstract int Count { get; }
public bool IsReadOnly => false;
public bool IsFixedSize => false;
public bool IsSynchronized => true;
public object SyncRoot => gate;
public abstract event NotifyCollectionChangedEventHandler? CollectionChanged;
public abstract event PropertyChangedEventHandler? PropertyChanged;
public abstract void Add(TView item);
int IList.Add(object? value)
{
Add((TView)value!);
return -1; // itself does not add in this collection
}
public abstract bool Contains(TView item);
bool IList.Contains(object? value)
{
if (IsCompatibleObject(value))
{
return Contains((TView)value!);
}
return false;
}
public abstract void Dispose();
public abstract IEnumerator<TView> GetEnumerator();
public abstract int IndexOf(TView item);
int IList.IndexOf(object? item)
{
if (IsCompatibleObject(item))
{
return IndexOf((TView)item!);
}
return -1;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
static bool IsCompatibleObject(object? value)
{
return value is TView || value == null && default(TView) == null;
}
void ICollection<TView>.Clear() => throw new NotSupportedException();
void IList.Clear() => throw new NotSupportedException();
void ICollection<TView>.CopyTo(TView[] array, int arrayIndex) => throw new NotSupportedException();
void ICollection.CopyTo(Array array, int index) => throw new NotSupportedException();
void IList<TView>.Insert(int index, TView item) => throw new NotSupportedException();
void IList.Insert(int index, object? value) => throw new NotSupportedException();
bool ICollection<TView>.Remove(TView item) => throw new NotSupportedException();
void IList.Remove(object? value) => throw new NotSupportedException();
void IList.RemoveAt(int index) => throw new NotSupportedException();
void IList<TView>.RemoveAt(int index) => throw new NotSupportedException();
}
public static class ObservableCollectionExtensions public static class ObservableCollectionExtensions
{ {
public static ISynchronizedViewList<T> ToViewList<T>(this IObservableCollection<T> collection) public static ISynchronizedViewList<T> ToViewList<T>(this IObservableCollection<T> collection)
@ -86,7 +173,7 @@ namespace ObservableCollections
public static ISynchronizedViewList<TView> ToViewList<T, TView>(this IObservableCollection<T> collection, Func<T, TView> transform) public static ISynchronizedViewList<TView> ToViewList<T, TView>(this IObservableCollection<T> collection, Func<T, TView> transform)
{ {
// Optimized for non filtered // Optimized for non filtered
return new NonFilteredSynchronizedViewList<T, TView>(collection.CreateView(transform)); return new NonFilteredSynchronizedViewList<T, TView>(collection.CreateView(transform), isSupportRangeFeature: true, null, null);
} }
public static INotifyCollectionChangedSynchronizedViewList<T> ToNotifyCollectionChanged<T>(this IObservableCollection<T> collection) public static INotifyCollectionChangedSynchronizedViewList<T> ToNotifyCollectionChanged<T>(this IObservableCollection<T> collection)
@ -107,7 +194,7 @@ namespace ObservableCollections
public static INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged<T, TView>(this IObservableCollection<T> collection, Func<T, TView> transform, ICollectionEventDispatcher? collectionEventDispatcher) public static INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged<T, TView>(this IObservableCollection<T> collection, Func<T, TView> transform, ICollectionEventDispatcher? collectionEventDispatcher)
{ {
// Optimized for non filtered // Optimized for non filtered
return new NonFilteredNotifyCollectionChangedSynchronizedViewList<T, TView>(collection.CreateView(transform), collectionEventDispatcher); return new NonFilteredSynchronizedViewList<T, TView>(collection.CreateView(transform), isSupportRangeFeature: false, collectionEventDispatcher, null);
} }
} }
} }

View File

@ -111,17 +111,17 @@ namespace ObservableCollections
public ISynchronizedViewList<TView> ToViewList() public ISynchronizedViewList<TView> ToViewList()
{ {
return new FiltableSynchronizedViewList<KeyValuePair<TKey, TValue>, TView>(this); return new FiltableSynchronizedViewList<KeyValuePair<TKey, TValue>, TView>(this, isSupportRangeFeature: true);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged() public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
{ {
return new NotifyCollectionChangedSynchronizedViewList<KeyValuePair<TKey, TValue>, TView>(this, null); return new FiltableSynchronizedViewList<KeyValuePair<TKey, TValue>, TView>(this, isSupportRangeFeature: false);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher)
{ {
return new NotifyCollectionChangedSynchronizedViewList<KeyValuePair<TKey, TValue>, TView>(this, collectionEventDispatcher); return new FiltableSynchronizedViewList<KeyValuePair<TKey, TValue>, TView>(this, isSupportRangeFeature: false, collectionEventDispatcher);
} }
public IEnumerator<TView> GetEnumerator() public IEnumerator<TView> GetEnumerator()

View File

@ -106,17 +106,17 @@ namespace ObservableCollections
public ISynchronizedViewList<TView> ToViewList() public ISynchronizedViewList<TView> ToViewList()
{ {
return new FiltableSynchronizedViewList<T, TView>(this); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: true);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged() public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, null); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, collectionEventDispatcher); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false, collectionEventDispatcher);
} }
public IEnumerator<TView> GetEnumerator() public IEnumerator<TView> GetEnumerator()

View File

@ -43,7 +43,7 @@ namespace ObservableCollections
public INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged<TView>(Func<T, TView> transform, WritableViewChangedEventHandler<T, TView>? converter, ICollectionEventDispatcher? collectionEventDispatcher) public INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged<TView>(Func<T, TView> transform, WritableViewChangedEventHandler<T, TView>? converter, ICollectionEventDispatcher? collectionEventDispatcher)
{ {
return new NonFilteredNotifyCollectionChangedSynchronizedViewList<T, TView>(CreateView(transform), collectionEventDispatcher, converter); return new NonFilteredSynchronizedViewList<T, TView>(CreateView(transform), isSupportRangeFeature: false, collectionEventDispatcher, converter);
} }
internal sealed class View<TView> : ISynchronizedView<T, TView>, IWritableSynchronizedView<T, TView> internal sealed class View<TView> : ISynchronizedView<T, TView>, IWritableSynchronizedView<T, TView>
@ -141,17 +141,17 @@ namespace ObservableCollections
public ISynchronizedViewList<TView> ToViewList() public ISynchronizedViewList<TView> ToViewList()
{ {
return new FiltableSynchronizedViewList<T, TView>(this); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: true);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged() public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, null); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, collectionEventDispatcher); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false, collectionEventDispatcher);
} }
public IEnumerator<TView> GetEnumerator() public IEnumerator<TView> GetEnumerator()
@ -370,27 +370,29 @@ namespace ObservableCollections
public IWritableSynchronizedViewList<TView> ToWritableViewList(WritableViewChangedEventHandler<T, TView> converter) public IWritableSynchronizedViewList<TView> ToWritableViewList(WritableViewChangedEventHandler<T, TView> converter)
{ {
return new FiltableWritableSynchronizedViewList<T, TView>(this, converter); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: true, converter: converter);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter) public NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, null, converter); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false, converter: converter);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) public NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, collectionEventDispatcher, return new FiltableSynchronizedViewList<T, TView>(this,
static (TView newView, T originalValue, ref bool setValue) => isSupportRangeFeature: false,
{ collectionEventDispatcher,
setValue = true; static (TView newView, T originalValue, ref bool setValue) =>
return originalValue; {
}); setValue = true;
return originalValue;
});
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter, ICollectionEventDispatcher? collectionEventDispatcher) public NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter, ICollectionEventDispatcher? collectionEventDispatcher)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, collectionEventDispatcher, converter); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false, collectionEventDispatcher, converter);
} }
#endregion #endregion

View File

@ -106,17 +106,17 @@ namespace ObservableCollections
public ISynchronizedViewList<TView> ToViewList() public ISynchronizedViewList<TView> ToViewList()
{ {
return new FiltableSynchronizedViewList<T, TView>(this); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: true);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged() public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, null); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, collectionEventDispatcher); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false, collectionEventDispatcher);
} }
public IEnumerator<TView> GetEnumerator() public IEnumerator<TView> GetEnumerator()

View File

@ -108,22 +108,22 @@ namespace ObservableCollections
public ISynchronizedViewList<TView> ToViewList() public ISynchronizedViewList<TView> ToViewList()
{ {
return new FiltableSynchronizedViewList<T, TView>(this); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: true);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged() public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
{ {
lock (SyncRoot) lock (SyncRoot)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, null); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false);
} }
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher)
{ {
lock (SyncRoot) lock (SyncRoot)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, collectionEventDispatcher); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false, collectionEventDispatcher);
} }
} }

View File

@ -105,22 +105,22 @@ namespace ObservableCollections
public ISynchronizedViewList<TView> ToViewList() public ISynchronizedViewList<TView> ToViewList()
{ {
return new FiltableSynchronizedViewList<T, TView>(this); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: true);
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged() public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
{ {
lock (SyncRoot) lock (SyncRoot)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, null); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false);
} }
} }
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher)
{ {
lock (SyncRoot) lock (SyncRoot)
{ {
return new NotifyCollectionChangedSynchronizedViewList<T, TView>(this, collectionEventDispatcher); return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false, collectionEventDispatcher);
} }
} }

File diff suppressed because it is too large Load Diff