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));