Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

ObservableCollectionとReadOnlyObservableCollectionの同期

$
0
0

ReactivePropertyのAPIに依存してますが、こういうのを用意しておけばいい感じ??

publicstaticclass ObservableCollectionExtensions
{
    publicstatic IDisposable ConnectToReadOnlyCollection<TType, TResult>(
        this ObservableCollection<TType> self, 
        out ReadOnlyObservableCollection<TResult> target, 
        Func<TType, TResult> converter)
    {
        var d = new CompositeDisposable();

        ObservableCollection<TResult> proxy = new ObservableCollection<TResult>(self.Select(t => converter(t)).ToArray());
        target = new ReadOnlyObservableCollection<TResult>(proxy);

        var collectionChanged = self.CollectionChangedAsObservable();
        collectionChanged.Where(e => e.Action == NotifyCollectionChangedAction.Add)
            .Select(e => new { Index = e.NewStartingIndex, Value = converter(e.NewItems.Cast<TType>().First()) })
            .Subscribe(v => proxy.Insert(v.Index, v.Value))
            .AddTo(d);
        collectionChanged.Where(e => e.Action == NotifyCollectionChangedAction.Move)
            .Select(e => new { OldIndex = e.OldStartingIndex, NewIndex = e.NewStartingIndex })
            .Subscribe(v => 
            {
                var item = proxy[v.OldIndex];
                proxy.RemoveAt(v.OldIndex);
                proxy.Insert(v.NewIndex, item);
            })
            .AddTo(d);
        collectionChanged.Where(e => e.Action == NotifyCollectionChangedAction.Remove)
            .Select(e => new { Index = e.OldStartingIndex })
            .Subscribe(v => proxy.RemoveAt(v.Index))
            .AddTo(d);
        collectionChanged.Where(e => e.Action == NotifyCollectionChangedAction.Replace)
            .Select(e => new { Index = e.NewStartingIndex, Item = converter(e.NewItems.Cast<TType>().First()) })
            .Subscribe(v => proxy[v.Index] = v.Item)
            .AddTo(d);
        collectionChanged.Where(e => e.Action == NotifyCollectionChangedAction.Reset)
            .Subscribe(_ =>
            {
                proxy.Clear();
                foreach (var item in self.ToArray())
                {
                    proxy.Add(converter(item));
                }
            })
            .AddTo(d);

        return d;
    }
}

使い方

// TodoItemsがObservableCollectionでthis.todoItemsがReadOnlyObservableCollection
TodoManager.Curret.TodoItems.ConnectToReadOnlyCollection(
    outthis.todoItems,
    t => new TodoItemViewModel(t));

Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>