Add R3 ObserveChanged
This commit is contained in:
parent
8b75c41da7
commit
8913192459
30
README.md
30
README.md
@ -50,6 +50,7 @@ ObservableCollections has not just a simple list, there are many more data struc
|
|||||||
If you want to handle each change event with Rx, you can monitor it with the following method by combining it with [R3](https://github.com/Cysharp/R3):
|
If you want to handle each change event with Rx, you can monitor it with the following method by combining it with [R3](https://github.com/Cysharp/R3):
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
Observable<CollectionChangedEvent<T>> IObservableCollection<T>.ObserveChanged()
|
||||||
Observable<CollectionAddEvent<T>> IObservableCollection<T>.ObserveAdd()
|
Observable<CollectionAddEvent<T>> IObservableCollection<T>.ObserveAdd()
|
||||||
Observable<CollectionRemoveEvent<T>> IObservableCollection<T>.ObserveRemove()
|
Observable<CollectionRemoveEvent<T>> IObservableCollection<T>.ObserveRemove()
|
||||||
Observable<CollectionReplaceEvent<T>> IObservableCollection<T>.ObserveReplace()
|
Observable<CollectionReplaceEvent<T>> IObservableCollection<T>.ObserveReplace()
|
||||||
@ -237,7 +238,7 @@ class DescendantComaprer : IComparer<int>
|
|||||||
|
|
||||||
Reactive Extensions with R3
|
Reactive Extensions with R3
|
||||||
---
|
---
|
||||||
Once the R3 extension package is installed, you can subscribe to `ObserveAdd`, `ObserveRemove`, `ObserveReplace`, `ObserveMove`, `ObserveReset`, `ObserveClear`, `ObserveReverse`, `ObserveSort` events as Rx, allowing you to compose events individually.
|
Once the R3 extension package is installed, you can subscribe to `ObserveChanged`, `ObserveAdd`, `ObserveRemove`, `ObserveReplace`, `ObserveMove`, `ObserveReset`, `ObserveClear`, `ObserveReverse`, `ObserveSort` events as Rx, allowing you to compose events individually.
|
||||||
|
|
||||||
> dotnet add package [ObservableCollections.R3](https://www.nuget.org/packages/ObservableCollections.R3)
|
> dotnet add package [ObservableCollections.R3](https://www.nuget.org/packages/ObservableCollections.R3)
|
||||||
|
|
||||||
@ -317,7 +318,7 @@ Because of data binding in WPF, it is important that the collection is Observabl
|
|||||||
// WPF simple sample.
|
// WPF simple sample.
|
||||||
|
|
||||||
ObservableList<int> list;
|
ObservableList<int> list;
|
||||||
public INotifyCollectionChangedSynchronizedViewList<int> ItemsView { get; set; }
|
public NotifyCollectionChangedSynchronizedViewList<int> ItemsView { get; set; }
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
@ -366,8 +367,8 @@ public delegate T WritableViewChangedEventHandler<T, TView>(TView newView, T ori
|
|||||||
|
|
||||||
public interface IWritableSynchronizedView<T, TView> : ISynchronizedView<T, TView>
|
public interface IWritableSynchronizedView<T, TView> : ISynchronizedView<T, TView>
|
||||||
{
|
{
|
||||||
INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter);
|
NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter);
|
||||||
INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter, ICollectionEventDispatcher? collectionEventDispatcher);
|
NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged(WritableViewChangedEventHandler<T, TView> converter, ICollectionEventDispatcher? collectionEventDispatcher);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -564,8 +565,8 @@ public interface ISynchronizedView<T, TView> : IReadOnlyCollection<TView>, IDisp
|
|||||||
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);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -630,10 +631,10 @@ public sealed partial class ObservableList<T>
|
|||||||
{
|
{
|
||||||
public IWritableSynchronizedView<T, TView> CreateWritableView<TView>(Func<T, TView> transform);
|
public IWritableSynchronizedView<T, TView> CreateWritableView<TView>(Func<T, TView> transform);
|
||||||
|
|
||||||
public INotifyCollectionChangedSynchronizedViewList<T> ToWritableNotifyCollectionChanged();
|
public NotifyCollectionChangedSynchronizedViewList<T> ToWritableNotifyCollectionChanged();
|
||||||
public INotifyCollectionChangedSynchronizedViewList<T> ToWritableNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher);
|
public NotifyCollectionChangedSynchronizedViewList<T> ToWritableNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher);
|
||||||
public INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged<TView>(Func<T, TView> transform, WritableViewChangedEventHandler<T, TView>? converter);
|
public NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged<TView>(Func<T, TView> transform, WritableViewChangedEventHandler<T, TView>? converter);
|
||||||
public INotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged<TView>(Func<T, TView> transform, ICollectionEventDispatcher? collectionEventDispatcher, WritableViewChangedEventHandler<T, TView>? converter);
|
public NotifyCollectionChangedSynchronizedViewList<TView> ToWritableNotifyCollectionChanged<TView>(Func<T, TView> transform, ICollectionEventDispatcher? collectionEventDispatcher, WritableViewChangedEventHandler<T, TView>? converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate T WritableViewChangedEventHandler<T, TView>(TView newView, T originalValue, ref bool setValue);
|
public delegate T WritableViewChangedEventHandler<T, TView>(TView newView, T originalValue, ref bool setValue);
|
||||||
@ -671,9 +672,18 @@ public interface ISynchronizedViewList<out TView> : IReadOnlyList<TView>, IDispo
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obsolete for public use
|
||||||
public interface INotifyCollectionChangedSynchronizedViewList<out TView> : ISynchronizedViewList<TView>, INotifyCollectionChanged, INotifyPropertyChanged
|
public interface INotifyCollectionChangedSynchronizedViewList<out TView> : ISynchronizedViewList<TView>, INotifyCollectionChanged, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract class NotifyCollectionChangedSynchronizedViewList<TView> :
|
||||||
|
INotifyCollectionChangedSynchronizedViewList<TView>,
|
||||||
|
IWritableSynchronizedViewList<TView>,
|
||||||
|
IList<TView>,
|
||||||
|
IList
|
||||||
|
{
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
License
|
License
|
||||||
|
@ -39,6 +39,11 @@ var bindable = view.ToWritableNotifyCollectionChanged((string? newView, Person o
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
list.Clear();
|
||||||
|
|
||||||
|
list.Add(new() { Age = 99, Name = "tako" });
|
||||||
|
|
||||||
// bindable[0] = "takoyaki";
|
// bindable[0] = "takoyaki";
|
||||||
|
|
||||||
foreach (var item in view)
|
foreach (var item in view)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using R3;
|
using R3;
|
||||||
|
|
||||||
@ -27,15 +28,40 @@ public readonly record struct CollectionResetEvent<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Auto)]
|
||||||
|
public readonly record struct CollectionChangedEvent<T>
|
||||||
|
{
|
||||||
|
public readonly NotifyCollectionChangedAction Action;
|
||||||
|
public readonly T NewItem;
|
||||||
|
public readonly T OldItem;
|
||||||
|
public readonly int NewStartingIndex;
|
||||||
|
public readonly int OldStartingIndex;
|
||||||
|
public readonly SortOperation<T> SortOperation;
|
||||||
|
|
||||||
|
public CollectionChangedEvent(NotifyCollectionChangedAction action, T newItem, T oldItem, int newStartingIndex, int oldStartingIndex, SortOperation<T> sortOperation)
|
||||||
|
{
|
||||||
|
Action = action;
|
||||||
|
NewItem = newItem;
|
||||||
|
OldItem = oldItem;
|
||||||
|
NewStartingIndex = newStartingIndex;
|
||||||
|
OldStartingIndex = oldStartingIndex;
|
||||||
|
SortOperation = sortOperation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public readonly record struct DictionaryAddEvent<TKey, TValue>(TKey Key, TValue Value);
|
public readonly record struct DictionaryAddEvent<TKey, TValue>(TKey Key, TValue Value);
|
||||||
|
|
||||||
public readonly record struct DictionaryRemoveEvent<TKey, TValue>(TKey Key, TValue Value);
|
public readonly record struct DictionaryRemoveEvent<TKey, TValue>(TKey Key, TValue Value);
|
||||||
|
|
||||||
public readonly record struct DictionaryReplaceEvent<TKey, TValue>(TKey Key, TValue OldValue, TValue NewValue);
|
public readonly record struct DictionaryReplaceEvent<TKey, TValue>(TKey Key, TValue OldValue, TValue NewValue);
|
||||||
|
|
||||||
|
|
||||||
public static class ObservableCollectionR3Extensions
|
public static class ObservableCollectionR3Extensions
|
||||||
{
|
{
|
||||||
|
public static Observable<CollectionChangedEvent<T>> ObserveChanged<T>(this IObservableCollection<T> source, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return new ObservableCollectionChanged<T>(source, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
public static Observable<CollectionAddEvent<T>> ObserveAdd<T>(this IObservableCollection<T> source, CancellationToken cancellationToken = default)
|
public static Observable<CollectionAddEvent<T>> ObserveAdd<T>(this IObservableCollection<T> source, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return new ObservableCollectionAdd<T>(source, cancellationToken);
|
return new ObservableCollectionAdd<T>(source, cancellationToken);
|
||||||
@ -102,6 +128,72 @@ public static class ObservableDictionaryR3Extensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class ObservableCollectionChanged<T>(IObservableCollection<T> collection, CancellationToken cancellationToken)
|
||||||
|
: Observable<CollectionChangedEvent<T>>
|
||||||
|
{
|
||||||
|
protected override IDisposable SubscribeCore(Observer<CollectionChangedEvent<T>> observer)
|
||||||
|
{
|
||||||
|
return new _ObservableCollectionAdd(collection, observer, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class _ObservableCollectionAdd(
|
||||||
|
IObservableCollection<T> collection,
|
||||||
|
Observer<CollectionChangedEvent<T>> observer,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
: ObservableCollectionObserverBase<T, CollectionChangedEvent<T>>(collection, observer, cancellationToken)
|
||||||
|
{
|
||||||
|
protected override void Handler(in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||||
|
{
|
||||||
|
if (eventArgs.IsSingleItem)
|
||||||
|
{
|
||||||
|
var newArgs = new CollectionChangedEvent<T>(
|
||||||
|
eventArgs.Action,
|
||||||
|
eventArgs.NewItem,
|
||||||
|
eventArgs.OldItem,
|
||||||
|
eventArgs.NewStartingIndex,
|
||||||
|
eventArgs.OldStartingIndex,
|
||||||
|
eventArgs.SortOperation);
|
||||||
|
|
||||||
|
observer.OnNext(newArgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (eventArgs.Action == NotifyCollectionChangedAction.Add)
|
||||||
|
{
|
||||||
|
var i = eventArgs.NewStartingIndex;
|
||||||
|
foreach (var item in eventArgs.NewItems)
|
||||||
|
{
|
||||||
|
var newArgs = new CollectionChangedEvent<T>(
|
||||||
|
eventArgs.Action,
|
||||||
|
eventArgs.NewItem,
|
||||||
|
eventArgs.OldItem,
|
||||||
|
i++,
|
||||||
|
eventArgs.OldStartingIndex,
|
||||||
|
eventArgs.SortOperation);
|
||||||
|
|
||||||
|
observer.OnNext(newArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventArgs.Action == NotifyCollectionChangedAction.Remove)
|
||||||
|
{
|
||||||
|
foreach (var item in eventArgs.OldItems)
|
||||||
|
{
|
||||||
|
var newArgs = new CollectionChangedEvent<T>(
|
||||||
|
eventArgs.Action,
|
||||||
|
eventArgs.NewItem,
|
||||||
|
eventArgs.OldItem,
|
||||||
|
eventArgs.NewStartingIndex,
|
||||||
|
eventArgs.OldStartingIndex, // removed, uses same index
|
||||||
|
eventArgs.SortOperation);
|
||||||
|
|
||||||
|
observer.OnNext(newArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sealed class ObservableCollectionAdd<T>(IObservableCollection<T> collection, CancellationToken cancellationToken)
|
sealed class ObservableCollectionAdd<T>(IObservableCollection<T> collection, CancellationToken cancellationToken)
|
||||||
: Observable<CollectionAddEvent<T>>
|
: Observable<CollectionAddEvent<T>>
|
||||||
{
|
{
|
||||||
@ -161,10 +253,9 @@ sealed class ObservableCollectionRemove<T>(IObservableCollection<T> collection,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var i = eventArgs.OldStartingIndex;
|
|
||||||
foreach (var item in eventArgs.OldItems)
|
foreach (var item in eventArgs.OldItems)
|
||||||
{
|
{
|
||||||
observer.OnNext(new CollectionRemoveEvent<T>(i++, item));
|
observer.OnNext(new CollectionRemoveEvent<T>(eventArgs.OldStartingIndex, item)); // remove uses same index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public partial class ObservableList<T> : IList<T>, IReadOnlyObservableList<T>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create faster, compact INotifyCollectionChanged view, however it does not support ***Range.
|
/// Create faster, compact INotifyCollectionChanged view, however it does not support ***Range.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public INotifyCollectionChangedSynchronizedViewList<T> ToNotifyCollectionChangedSlim()
|
public NotifyCollectionChangedSynchronizedViewList<T> ToNotifyCollectionChangedSlim()
|
||||||
{
|
{
|
||||||
return new ObservableListSynchronizedViewList<T>(this, null);
|
return new ObservableListSynchronizedViewList<T>(this, null);
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ public partial class ObservableList<T> : IList<T>, IReadOnlyObservableList<T>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create faster, compact INotifyCollectionChanged view, however it does not support ***Range.
|
/// Create faster, compact INotifyCollectionChanged view, however it does not support ***Range.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public INotifyCollectionChangedSynchronizedViewList<T> ToNotifyCollectionChangedSlim(ICollectionEventDispatcher? collectionEventDispatcher)
|
public NotifyCollectionChangedSynchronizedViewList<T> ToNotifyCollectionChangedSlim(ICollectionEventDispatcher? collectionEventDispatcher)
|
||||||
{
|
{
|
||||||
return new ObservableListSynchronizedViewList<T>(this, collectionEventDispatcher);
|
return new ObservableListSynchronizedViewList<T>(this, collectionEventDispatcher);
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ public partial class ObservableList<T> : IList<T>, IReadOnlyObservableList<T>
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class ObservableListSynchronizedViewList<T> : INotifyCollectionChangedSynchronizedViewList<T>, IList<T>, IList
|
internal sealed class ObservableListSynchronizedViewList<T> : NotifyCollectionChangedSynchronizedViewList<T>
|
||||||
{
|
{
|
||||||
static readonly PropertyChangedEventArgs CountPropertyChangedEventArgs = new("Count");
|
static readonly PropertyChangedEventArgs CountPropertyChangedEventArgs = new("Count");
|
||||||
static readonly Action<NotifyCollectionChangedEventArgs> raiseChangedEventInvoke = RaiseChangedEvent;
|
static readonly Action<NotifyCollectionChangedEventArgs> raiseChangedEventInvoke = RaiseChangedEvent;
|
||||||
@ -56,8 +56,8 @@ internal sealed class ObservableListSynchronizedViewList<T> : INotifyCollectionC
|
|||||||
readonly ObservableList<T> parent;
|
readonly ObservableList<T> parent;
|
||||||
readonly ICollectionEventDispatcher eventDispatcher;
|
readonly ICollectionEventDispatcher eventDispatcher;
|
||||||
|
|
||||||
public event NotifyCollectionChangedEventHandler? CollectionChanged;
|
public override event NotifyCollectionChangedEventHandler? CollectionChanged;
|
||||||
public event PropertyChangedEventHandler? PropertyChanged;
|
public override event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
public ObservableListSynchronizedViewList(ObservableList<T> parent, ICollectionEventDispatcher? eventDispatcher)
|
public ObservableListSynchronizedViewList(ObservableList<T> parent, ICollectionEventDispatcher? eventDispatcher)
|
||||||
{
|
{
|
||||||
@ -161,130 +161,42 @@ internal sealed class ObservableListSynchronizedViewList<T> : INotifyCollectionC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T this[int index] => parent[index];
|
public override T this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return parent[index];
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
parent[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int Count => parent.Count;
|
public override int Count => parent.Count;
|
||||||
|
|
||||||
public IEnumerator<T> GetEnumerator()
|
public override IEnumerator<T> GetEnumerator()
|
||||||
{
|
{
|
||||||
return parent.GetEnumerator();
|
return parent.GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
public override void Dispose()
|
||||||
{
|
|
||||||
return parent.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
{
|
||||||
parent.CollectionChanged -= Parent_CollectionChanged;
|
parent.CollectionChanged -= Parent_CollectionChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IList<T>, IList implementation
|
public override void Add(T item)
|
||||||
|
|
||||||
T IList<T>.this[int index]
|
|
||||||
{
|
{
|
||||||
get => ((IReadOnlyList<T>)this)[index];
|
parent.Add(item);
|
||||||
set => throw new NotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object? IList.this[int index]
|
public override bool Contains(T item)
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this[index];
|
|
||||||
}
|
|
||||||
set => throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsCompatibleObject(object? value)
|
|
||||||
{
|
|
||||||
return value is T || value == null && default(T) == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsReadOnly => true;
|
|
||||||
|
|
||||||
public bool IsFixedSize => false;
|
|
||||||
|
|
||||||
public bool IsSynchronized => true;
|
|
||||||
|
|
||||||
public object SyncRoot => parent.SyncRoot;
|
|
||||||
|
|
||||||
public void Add(T item)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Add(object? value)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Contains(T item)
|
|
||||||
{
|
{
|
||||||
return parent.Contains(item);
|
return parent.Contains(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains(object? value)
|
public override int IndexOf(T item)
|
||||||
{
|
|
||||||
if (IsCompatibleObject(value))
|
|
||||||
{
|
|
||||||
return Contains((T)value!);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyTo(T[] array, int arrayIndex)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyTo(Array array, int index)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int IndexOf(T item)
|
|
||||||
{
|
{
|
||||||
return parent.IndexOf(item);
|
return parent.IndexOf(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int IndexOf(object? item)
|
|
||||||
{
|
|
||||||
if (IsCompatibleObject(item))
|
|
||||||
{
|
|
||||||
return IndexOf((T)item!);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Insert(int index, T item)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Insert(int index, object? value)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Remove(T item)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove(object? value)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAt(int index)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -174,7 +174,7 @@ namespace ObservableCollections
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ev2?.Invoke(RejectedViewChangedAction.Remove, index, -1);
|
ev2?.Invoke(RejectedViewChangedAction.Remove, index, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user