ObservableList.View.ToNotifyCollectionChanged collection implements IList(allow binding for Avalonia)
This commit is contained in:
parent
f2e26e95a3
commit
fa6a843a49
@ -1,5 +1,6 @@
|
|||||||
using ObservableCollections.Internal;
|
using ObservableCollections.Internal;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@ -15,11 +16,11 @@ namespace ObservableCollections
|
|||||||
ISynchronizedView<T, TView> CreateView<TView>(Func<T, TView> transform, bool reverse = false);
|
ISynchronizedView<T, TView> CreateView<TView>(Func<T, TView> transform, bool reverse = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IReadOnlyObservableDictionary<TKey, TValue> :
|
public interface IReadOnlyObservableDictionary<TKey, TValue> :
|
||||||
IReadOnlyDictionary<TKey, TValue>, IObservableCollection<KeyValuePair<TKey, TValue>>
|
IReadOnlyDictionary<TKey, TValue>, IObservableCollection<KeyValuePair<TKey, TValue>>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IFreezedCollection<T>
|
public interface IFreezedCollection<T>
|
||||||
{
|
{
|
||||||
ISynchronizedView<T, TView> CreateView<TView>(Func<T, TView> transform, bool reverse = false);
|
ISynchronizedView<T, TView> CreateView<TView>(Func<T, TView> transform, bool reverse = false);
|
||||||
|
@ -132,4 +132,152 @@ namespace ObservableCollections.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class ListNotifyCollectionChangedSynchronizedView<T, TView>
|
||||||
|
: NotifyCollectionChangedSynchronizedView<T, TView>
|
||||||
|
, IList<TView>
|
||||||
|
, IList
|
||||||
|
{
|
||||||
|
readonly ObservableList<T>.View<TView> view;
|
||||||
|
|
||||||
|
public ListNotifyCollectionChangedSynchronizedView(ObservableList<T>.View<TView> parent, ICollectionEventDispatcher? eventDispatcher)
|
||||||
|
: base(parent, eventDispatcher)
|
||||||
|
{
|
||||||
|
this.view = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TView this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (view.SyncRoot)
|
||||||
|
{
|
||||||
|
return view.list[index].Item2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set => throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
object? IList.this[int index]
|
||||||
|
{
|
||||||
|
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 => view.SyncRoot;
|
||||||
|
|
||||||
|
public void Add(TView item)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Add(object? value)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(TView item)
|
||||||
|
{
|
||||||
|
lock (view.SyncRoot)
|
||||||
|
{
|
||||||
|
foreach (var listItem in view.list)
|
||||||
|
{
|
||||||
|
if (EqualityComparer<TView>.Default.Equals(listItem.Item2, item))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(object? value)
|
||||||
|
{
|
||||||
|
if (IsCompatibleObject(value))
|
||||||
|
{
|
||||||
|
return Contains((TView)value!);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo(TView[] array, int arrayIndex)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo(Array array, int index)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOf(TView item)
|
||||||
|
{
|
||||||
|
lock (view.SyncRoot)
|
||||||
|
{
|
||||||
|
var index = 0;
|
||||||
|
foreach (var listItem in view.list)
|
||||||
|
{
|
||||||
|
if (EqualityComparer<TView>.Default.Equals(listItem.Item2, item))
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOf(object? item)
|
||||||
|
{
|
||||||
|
if (IsCompatibleObject(item))
|
||||||
|
{
|
||||||
|
return IndexOf((TView)item!);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(int index, TView item)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(int index, object? value)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Remove(TView item)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(object? value)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveAt(int index)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ namespace ObservableCollections
|
|||||||
return new View<TView>(this, transform, reverse);
|
return new View<TView>(this, transform, reverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class View<TView> : ISynchronizedView<T, TView>
|
internal sealed class View<TView> : ISynchronizedView<T, TView>
|
||||||
{
|
{
|
||||||
public ISynchronizedViewFilter<T, TView> CurrentFilter
|
public ISynchronizedViewFilter<T, TView> CurrentFilter
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@ namespace ObservableCollections
|
|||||||
readonly ObservableList<T> source;
|
readonly ObservableList<T> source;
|
||||||
readonly Func<T, TView> selector;
|
readonly Func<T, TView> selector;
|
||||||
readonly bool reverse;
|
readonly bool reverse;
|
||||||
readonly List<(T, TView)> list;
|
internal readonly List<(T, TView)> list; // be careful to use
|
||||||
|
|
||||||
ISynchronizedViewFilter<T, TView> filter;
|
ISynchronizedViewFilter<T, TView> filter;
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
lock (SyncRoot)
|
lock (SyncRoot)
|
||||||
{
|
{
|
||||||
return new NotifyCollectionChangedSynchronizedView<T, TView>(this, null);
|
return new ListNotifyCollectionChangedSynchronizedView<T, TView>(this, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
lock (SyncRoot)
|
lock (SyncRoot)
|
||||||
{
|
{
|
||||||
return new NotifyCollectionChangedSynchronizedView<T, TView>(this, collectionEventDispatcher);
|
return new ListNotifyCollectionChangedSynchronizedView<T, TView>(this, collectionEventDispatcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user