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);
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)
{

View File

@ -47,8 +47,8 @@ namespace ObservableCollections
void AttachFilter(ISynchronizedViewFilter<T> filter);
void ResetFilter();
ISynchronizedViewList<TView> ToViewList();
INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged();
INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher);
NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged();
NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher);
}
public interface IWritableSynchronizedView<T, TView> : ISynchronizedView<T, TView>
@ -58,9 +58,9 @@ namespace ObservableCollections
void SetToSourceCollection(int index, T value);
void AddToSourceCollection(T value);
IWritableSynchronizedViewList<TView> ToWritableViewList(WritableViewChangedEventHandler<T, TView> converter);
INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter);
INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher);
INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter, ICollectionEventDispatcher? collectionEventDispatcher);
NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter);
NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher);
NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter, ICollectionEventDispatcher? collectionEventDispatcher);
}
public interface ISynchronizedViewList<out TView> : IReadOnlyList<TView>, IDisposable
@ -72,10 +72,97 @@ namespace ObservableCollections
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
{
}
// 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 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)
{
// 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)
@ -107,7 +194,7 @@ namespace ObservableCollections
public static INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged<T, TView>(this IObservableCollection<T> collection, Func<T, TView> transform, ICollectionEventDispatcher? collectionEventDispatcher)
{
// 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()
{
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()

View File

@ -106,17 +106,17 @@ namespace ObservableCollections
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()

View File

@ -43,7 +43,7 @@ namespace ObservableCollections
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>
@ -141,17 +141,17 @@ namespace ObservableCollections
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()
@ -370,27 +370,29 @@ namespace ObservableCollections
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,
static (TView newView, T originalValue, ref bool setValue) =>
{
setValue = true;
return originalValue;
});
return new FiltableSynchronizedViewList<T, TView>(this,
isSupportRangeFeature: false,
collectionEventDispatcher,
static (TView newView, T originalValue, ref bool setValue) =>
{
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

View File

@ -106,17 +106,17 @@ namespace ObservableCollections
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()

View File

@ -108,22 +108,22 @@ namespace ObservableCollections
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)
{
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)
{
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()
{
return new FiltableSynchronizedViewList<T, TView>(this);
return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: true);
}
public INotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
{
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)
{
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