todo
This commit is contained in:
parent
a7d6e51831
commit
d5f52ee6b7
@ -57,6 +57,10 @@ namespace ObservableCollections
|
|||||||
//{
|
//{
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
public interface ISynchronizedViewList<out TView> : IReadOnlyList<TView>, IDisposable
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public interface INotifyCollectionChangedSynchronizedView<out TView> : IReadOnlyCollection<TView>, INotifyCollectionChanged, INotifyPropertyChanged, IDisposable
|
public interface INotifyCollectionChangedSynchronizedView<out TView> : IReadOnlyCollection<TView>, INotifyCollectionChanged, INotifyPropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,8 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
return filter == SynchronizedViewFilter<T, TView>.Null;
|
return filter == SynchronizedViewFilter<T, TView>.Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static void InvokeOnAdd<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, int index)
|
internal static void InvokeOnAdd<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, int index)
|
||||||
{
|
{
|
||||||
filter.InvokeOnAdd(value.value, value.view, index);
|
filter.InvokeOnAdd(value.value, value.view, index);
|
||||||
@ -139,5 +139,10 @@ namespace ObservableCollections
|
|||||||
filter.WhenFalse(value, view);
|
filter.WhenFalse(value, view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool IsMatch<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T, TView) value)
|
||||||
|
{
|
||||||
|
return filter.IsMatch(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,117 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Collections;
|
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;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace ObservableCollections.Internal
|
namespace ObservableCollections.Internal
|
||||||
{
|
{
|
||||||
|
internal class SynchronizedViewList<T, TView> : ISynchronizedViewList<TView>
|
||||||
|
{
|
||||||
|
readonly ISynchronizedView<T, TView> parent;
|
||||||
|
readonly List<TView> listView;
|
||||||
|
readonly Func<T, TView> selector;
|
||||||
|
|
||||||
|
public SynchronizedViewList(ISynchronizedView<T, TView> parent, Func<T, TView> selector)
|
||||||
|
{
|
||||||
|
this.parent = parent;
|
||||||
|
this.selector = selector;
|
||||||
|
parent.RoutingCollectionChanged += Parent_RoutingCollectionChanged; // TODO: -=
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Parent_RoutingCollectionChanged(in NotifyCollectionChangedEventArgs<T> e)
|
||||||
|
{
|
||||||
|
// call in parent.lock.
|
||||||
|
switch (e.Action)
|
||||||
|
{
|
||||||
|
case NotifyCollectionChangedAction.Add:
|
||||||
|
if (e.IsSingleItem)
|
||||||
|
{
|
||||||
|
// parent.CurrentFilter.IsMatch(
|
||||||
|
|
||||||
|
var item = selector(e.NewItem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (e.NewStartingIndex != -1)
|
||||||
|
{
|
||||||
|
listView.Insert(e.NewStartingIndex, selector(e.NewItem));
|
||||||
|
}
|
||||||
|
else // dict is -1
|
||||||
|
{
|
||||||
|
listView.Add(selector(e.NewItem));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (e.NewStartingIndex != -1)
|
||||||
|
{
|
||||||
|
var array = ArrayPool<TView>.Shared.Rent(e.NewItems.Length);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
foreach (var item in e.NewItems)
|
||||||
|
{
|
||||||
|
array[i++] = selector(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
listView.InsertRange(e.NewStartingIndex, array.Take(e.NewItems.Length));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ArrayPool<TView>.Shared.Return(array, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var item in e.NewItems)
|
||||||
|
{
|
||||||
|
listView.Add(selector(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NotifyCollectionChangedAction.Remove:
|
||||||
|
break;
|
||||||
|
case NotifyCollectionChangedAction.Replace:
|
||||||
|
break;
|
||||||
|
case NotifyCollectionChangedAction.Move:
|
||||||
|
break;
|
||||||
|
case NotifyCollectionChangedAction.Reset:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TView this[int index] => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public int Count => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<TView> GetEnumerator()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal class NotifyCollectionChangedSynchronizedView<T, TView> :
|
internal class NotifyCollectionChangedSynchronizedView<T, TView> :
|
||||||
INotifyCollectionChangedSynchronizedView<TView>,
|
INotifyCollectionChangedSynchronizedView<TView>,
|
||||||
ISynchronizedViewFilter<T, TView>
|
ISynchronizedViewFilter<T, TView>
|
||||||
|
@ -27,7 +27,8 @@ 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;
|
||||||
internal readonly List<(T, TView)> list; // be careful to use
|
readonly List<(T, TView)> list;
|
||||||
|
int filteredCount;
|
||||||
|
|
||||||
ISynchronizedViewFilter<T, TView> filter;
|
ISynchronizedViewFilter<T, TView> filter;
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ namespace ObservableCollections
|
|||||||
lock (source.SyncRoot)
|
lock (source.SyncRoot)
|
||||||
{
|
{
|
||||||
this.list = source.list.Select(x => (x, selector(x))).ToList();
|
this.list = source.list.Select(x => (x, selector(x))).ToList();
|
||||||
|
this.filteredCount = list.Count;
|
||||||
this.source.CollectionChanged += SourceCollectionChanged;
|
this.source.CollectionChanged += SourceCollectionChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,7 +58,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
lock (SyncRoot)
|
lock (SyncRoot)
|
||||||
{
|
{
|
||||||
return list.Count;
|
return filteredCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,6 +162,10 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (e.NewItem, selector(e.NewItem));
|
var v = (e.NewItem, selector(e.NewItem));
|
||||||
list.Add(v);
|
list.Add(v);
|
||||||
|
if (filter.IsMatch(v))
|
||||||
|
{
|
||||||
|
filteredCount++;
|
||||||
|
}
|
||||||
filter.InvokeOnAdd(v, e.NewStartingIndex);
|
filter.InvokeOnAdd(v, e.NewStartingIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -169,6 +175,10 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (item, selector(item));
|
var v = (item, selector(item));
|
||||||
list.Add(v);
|
list.Add(v);
|
||||||
|
if (filter.IsMatch(v))
|
||||||
|
{
|
||||||
|
filteredCount++;
|
||||||
|
}
|
||||||
filter.InvokeOnAdd(v, i++);
|
filter.InvokeOnAdd(v, i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user