add Insert, Remove, RemoveAt, Clear, other
This commit is contained in:
parent
367be8717c
commit
62b959c2c2
@ -57,6 +57,10 @@ namespace ObservableCollections
|
||||
void SetViewAt(int index, TView view);
|
||||
void SetToSourceCollection(int index, T value);
|
||||
void AddToSourceCollection(T value);
|
||||
void InsertIntoSourceCollection(int index, T value);
|
||||
bool RemoveFromSourceCollection(T value);
|
||||
void RemoveAtSourceCollection(int index);
|
||||
void ClearSourceCollection();
|
||||
IWritableSynchronizedViewList<TView> ToWritableViewList(WritableViewChangedEventHandler<T, TView> converter);
|
||||
NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged();
|
||||
NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter);
|
||||
@ -100,8 +104,8 @@ namespace ObservableCollections
|
||||
}
|
||||
|
||||
public abstract int Count { get; }
|
||||
public bool IsReadOnly => false;
|
||||
public bool IsFixedSize => false;
|
||||
public virtual bool IsReadOnly { get; } = true;
|
||||
public bool IsFixedSize => IsReadOnly;
|
||||
public bool IsSynchronized => true;
|
||||
public object SyncRoot => gate;
|
||||
|
||||
@ -113,9 +117,14 @@ namespace ObservableCollections
|
||||
int IList.Add(object? value)
|
||||
{
|
||||
Add((TView)value!);
|
||||
return -1; // itself does not add in this collection
|
||||
return Count - 1;
|
||||
}
|
||||
|
||||
public abstract void Insert(int index, TView item);
|
||||
public abstract bool Remove(TView item);
|
||||
public abstract void RemoveAt(int index);
|
||||
public abstract void Clear();
|
||||
|
||||
public abstract bool Contains(TView item);
|
||||
|
||||
bool IList.Contains(object? value)
|
||||
@ -150,17 +159,43 @@ namespace ObservableCollections
|
||||
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>.Clear()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
void IList.Clear()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
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>.Insert(int index, TView item)
|
||||
{
|
||||
Insert(index, item);
|
||||
}
|
||||
|
||||
void IList.Insert(int index, object? value)
|
||||
{
|
||||
Insert(index, (TView)value!);
|
||||
}
|
||||
|
||||
bool ICollection<TView>.Remove(TView item)
|
||||
{
|
||||
return Remove(item!);
|
||||
}
|
||||
|
||||
void IList.Remove(object? value)
|
||||
{
|
||||
Remove((TView)value!);
|
||||
}
|
||||
|
||||
void IList.RemoveAt(int index)
|
||||
{
|
||||
RemoveAt(index);
|
||||
}
|
||||
|
||||
void IList<TView>.RemoveAt(int index) => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
|
@ -189,6 +189,25 @@ internal sealed class ObservableListSynchronizedViewList<T> : NotifyCollectionCh
|
||||
{
|
||||
parent.Add(item);
|
||||
}
|
||||
public override void Insert(int index, T item)
|
||||
{
|
||||
parent.Insert(index, item);
|
||||
}
|
||||
|
||||
public override bool Remove(T item)
|
||||
{
|
||||
return parent.Remove(item);
|
||||
}
|
||||
|
||||
public override void RemoveAt(int index)
|
||||
{
|
||||
parent.RemoveAt(index);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
parent.Clear();
|
||||
}
|
||||
|
||||
public override bool Contains(T item)
|
||||
{
|
||||
|
@ -367,6 +367,37 @@ namespace ObservableCollections
|
||||
source.Add(value);
|
||||
}
|
||||
}
|
||||
public void InsertIntoSourceCollection(int index, T value)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
source.Insert(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool RemoveFromSourceCollection(T value)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return source.Remove(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAtSourceCollection(int index)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
source.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearSourceCollection()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
source.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public IWritableSynchronizedViewList<TView> ToWritableViewList(WritableViewChangedEventHandler<T, TView> converter)
|
||||
{
|
||||
@ -393,8 +424,8 @@ namespace ObservableCollections
|
||||
{
|
||||
return new FiltableSynchronizedViewList<T, TView>(this,
|
||||
isSupportRangeFeature: false,
|
||||
collectionEventDispatcher,
|
||||
static (TView newView, T originalValue, ref bool setValue) =>
|
||||
eventDispatcher: collectionEventDispatcher,
|
||||
converter: static (TView newView, T originalValue, ref bool setValue) =>
|
||||
{
|
||||
setValue = true;
|
||||
return originalValue;
|
||||
|
@ -337,21 +337,22 @@ internal sealed class FiltableSynchronizedViewList<T, TView> : NotifyCollectionC
|
||||
}
|
||||
set
|
||||
{
|
||||
if (converter == null || parent is not IWritableSynchronizedView<T, TView> writableView)
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support set. If base type is ObservableList<T>, you can use ToWritableSynchronizedView and ToWritableNotifyCollectionChanged.");
|
||||
throw new NotSupportedException("This CollectionView does not support Set. If base type is ObservableList<T>, you can use CreateWritableView and ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
var originalIndex = listView.GetAlternateIndex(index);
|
||||
var (originalValue, _) = writableView.GetAt(originalIndex);
|
||||
var (originalValue, _) = writableView!.GetAt(originalIndex);
|
||||
|
||||
// update view
|
||||
writableView.SetViewAt(originalIndex, value);
|
||||
listView[index] = value;
|
||||
|
||||
var setValue = true;
|
||||
var newOriginal = converter(value, originalValue, ref setValue);
|
||||
var newOriginal = converter!(value, originalValue, ref setValue);
|
||||
|
||||
if (setValue)
|
||||
{
|
||||
@ -372,6 +373,8 @@ internal sealed class FiltableSynchronizedViewList<T, TView> : NotifyCollectionC
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsReadOnly => converter == null || parent is not IWritableSynchronizedView<T, TView>;
|
||||
|
||||
public override IEnumerator<TView> GetEnumerator()
|
||||
{
|
||||
lock (gate)
|
||||
@ -385,17 +388,91 @@ internal sealed class FiltableSynchronizedViewList<T, TView> : NotifyCollectionC
|
||||
|
||||
public override void Add(TView item)
|
||||
{
|
||||
if (converter == null || parent is not IWritableSynchronizedView<T, TView> writableView)
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support Add. If base type is ObservableList<T>, you can use ToWritableSynchronizedView and ToWritableNotifyCollectionChanged.");
|
||||
throw new NotSupportedException("This CollectionView does not support Add. If base type is ObservableList<T>, you can use CreateWritableView and ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
if (typeof(T) == typeof(TView) && item is T tItem)
|
||||
{
|
||||
writableView!.AddToSourceCollection(tItem);
|
||||
return;
|
||||
}
|
||||
var setValue = false;
|
||||
var newOriginal = converter(item, default!, ref setValue);
|
||||
var newOriginal = converter!(item, default!, ref setValue);
|
||||
|
||||
// always add
|
||||
writableView.AddToSourceCollection(newOriginal);
|
||||
writableView!.AddToSourceCollection(newOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Insert(int index, TView item)
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support Insert. If base type is ObservableList<T>, you can use CreateWritableView and ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
if (typeof(T) == typeof(TView) && item is T tItem)
|
||||
{
|
||||
writableView!.InsertIntoSourceCollection(index, tItem);
|
||||
return;
|
||||
}
|
||||
var setValue = false;
|
||||
var newOriginal = converter!(item, default!, ref setValue);
|
||||
|
||||
writableView!.InsertIntoSourceCollection(index, newOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Remove(TView item)
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support Remove. If base type is ObservableList<T>, you can use CreateWritableView and ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
if (typeof(T) == typeof(TView) && item is T tItem)
|
||||
{
|
||||
return writableView!.RemoveFromSourceCollection(tItem);
|
||||
}
|
||||
var setValue = false;
|
||||
var newOriginal = converter!(item, default!, ref setValue);
|
||||
|
||||
// always add
|
||||
return writableView!.RemoveFromSourceCollection(newOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
public override void RemoveAt(int index)
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support RemoveAt. If base type is ObservableList<T>, you can use CreateWritableView and ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
writableView!.RemoveAtSourceCollection(index);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support Clear. If base type is ObservableList<T>, you can use CreateWritableView and ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
writableView!.ClearSourceCollection();
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,20 +839,21 @@ internal sealed class NonFilteredSynchronizedViewList<T, TView> : NotifyCollecti
|
||||
}
|
||||
set
|
||||
{
|
||||
if (converter == null || parent is not IWritableSynchronizedView<T, TView> writableView)
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support set. If base type is ObservableList<T>, you can use ToWritableSynchronizedView and ToWritableNotifyCollectionChanged.");
|
||||
throw new NotSupportedException("This CollectionView does not support set. If base type is ObservableList<T>, you can use ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var (originalValue, _) = writableView.GetAt(index);
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
var (originalValue, _) = writableView!.GetAt(index);
|
||||
|
||||
// update view
|
||||
writableView.SetViewAt(index, value);
|
||||
listView[index] = value;
|
||||
|
||||
var setValue = true;
|
||||
var newOriginal = converter(value, originalValue, ref setValue);
|
||||
var newOriginal = converter!(value, originalValue, ref setValue);
|
||||
|
||||
if (setValue)
|
||||
{
|
||||
@ -796,6 +874,8 @@ internal sealed class NonFilteredSynchronizedViewList<T, TView> : NotifyCollecti
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsReadOnly => converter == null || parent is not IWritableSynchronizedView<T, TView>;
|
||||
|
||||
public override IEnumerator<TView> GetEnumerator()
|
||||
{
|
||||
lock (gate)
|
||||
@ -809,17 +889,91 @@ internal sealed class NonFilteredSynchronizedViewList<T, TView> : NotifyCollecti
|
||||
|
||||
public override void Add(TView item)
|
||||
{
|
||||
if (converter == null || parent is not IWritableSynchronizedView<T, TView> writableView)
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support Add. If base type is ObservableList<T>, you can use ToWritableSynchronizedView and ToWritableNotifyCollectionChanged.");
|
||||
throw new NotSupportedException("This CollectionView does not support Add. If base type is ObservableList<T>, you can use ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
if (typeof(T) == typeof(TView) && item is T tItem)
|
||||
{
|
||||
writableView!.AddToSourceCollection(tItem);
|
||||
return;
|
||||
}
|
||||
var setValue = false;
|
||||
var newOriginal = converter(item, default!, ref setValue);
|
||||
var newOriginal = converter!(item, default!, ref setValue);
|
||||
|
||||
// always add
|
||||
writableView.AddToSourceCollection(newOriginal);
|
||||
writableView!.AddToSourceCollection(newOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Insert(int index, TView item)
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support Insert. If base type is ObservableList<T>, you can use ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
if (typeof(T) == typeof(TView) && item is T tItem)
|
||||
{
|
||||
writableView!.InsertIntoSourceCollection(index, tItem);
|
||||
return;
|
||||
}
|
||||
var setValue = false;
|
||||
var newOriginal = converter!(item, default!, ref setValue);
|
||||
|
||||
writableView!.InsertIntoSourceCollection(index, newOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Remove(TView item)
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support Remove. If base type is ObservableList<T>, you can use ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
if (typeof(T) == typeof(TView) && item is T tItem)
|
||||
{
|
||||
return writableView!.RemoveFromSourceCollection(tItem);
|
||||
}
|
||||
var setValue = false;
|
||||
var newOriginal = converter!(item, default!, ref setValue);
|
||||
|
||||
// always add
|
||||
return writableView!.RemoveFromSourceCollection(newOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
public override void RemoveAt(int index)
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support RemoveAt. If base type is ObservableList<T>, you can use ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
writableView!.RemoveAtSourceCollection(index);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("This CollectionView does not support Clear. If base type is ObservableList<T>, you can use ToWritableNotifyCollectionChanged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var writableView = parent as IWritableSynchronizedView<T, TView>;
|
||||
writableView!.ClearSourceCollection();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user