示例#1
0
        protected virtual void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            if (disposing)
            {
                _listeners.Dispose();

                if (typeof(IDisposable).IsAssignableFrom(typeof(T)))
                {
                    foreach (var i in _list.OfType <IDisposable>())
                    {
                        i.Dispose();
                    }
                }
            }

            _disposed = true;
        }
示例#2
0
        public static ReadOnlyDispatcherCollection <TViewModel> CreateReadOnlyDispatcherCollection <TModel, TViewModel>(
            [NotNull] IList <TModel> source, [NotNull] Func <TModel, TViewModel> converter,
            [NotNull] Dispatcher dispatcher)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (converter == null)
            {
                throw new ArgumentNullException(nameof(converter));
            }
            if (dispatcher == null)
            {
                throw new ArgumentNullException(nameof(dispatcher));
            }

            if (!(source is INotifyCollectionChanged sourceAsNotifyCollection))
            {
                throw new ArgumentException("sourceがINotifyCollectionChangedを実装していません");
            }

            var initCollection = new ObservableCollection <TViewModel>();

            foreach (var model in source)
            {
                initCollection.Add(converter(model));
            }

            var target = new DispatcherCollection <TViewModel>(initCollection, dispatcher);
            var result = new ReadOnlyDispatcherCollection <TViewModel>(target);

            var collectionChangedListener = new CollectionChangedEventListener(sourceAsNotifyCollection);

            result.EventListeners.Add(collectionChangedListener);

            collectionChangedListener.RegisterHandler((sender, e) =>
            {
                if (e == null)
                {
                    throw new ArgumentNullException(nameof(e));
                }
                switch (e.Action)
                {
                case NotifyCollectionChangedAction.Add:
                    var vm = converter((TModel)e.NewItems?[0]);
                    InvokeOnDispatcher(() => target.Insert(e.NewStartingIndex, vm), dispatcher);
                    break;

                case NotifyCollectionChangedAction.Move:
                    InvokeOnDispatcher(() => target.Move(e.OldStartingIndex, e.NewStartingIndex), dispatcher);
                    break;

                case NotifyCollectionChangedAction.Remove:
                    if (typeof(IDisposable).IsAssignableFrom(typeof(TViewModel)))
                    {
                        ((IDisposable)target[e.OldStartingIndex])?.Dispose();
                    }
                    InvokeOnDispatcher(() => target.RemoveAt(e.OldStartingIndex), dispatcher);
                    break;

                case NotifyCollectionChangedAction.Replace:
                    if (typeof(IDisposable).IsAssignableFrom(typeof(TViewModel)))
                    {
                        ((IDisposable)target[e.NewStartingIndex])?.Dispose();
                    }
                    var replaceVm = converter((TModel)e.NewItems?[0]);
                    InvokeOnDispatcher(() => target[e.NewStartingIndex] = replaceVm, dispatcher);
                    break;

                case NotifyCollectionChangedAction.Reset:
                    if (typeof(IDisposable).IsAssignableFrom(typeof(TViewModel)))
                    {
                        foreach (var item in target.OfType <IDisposable>())
                        {
                            item.Dispose();
                        }
                    }

                    InvokeOnDispatcher(target.Clear, dispatcher);
                    break;

                default:
                    throw new ArgumentException();
                }
            });

            return(result);
        }