Ответ 1
Здесь решение: События CollectionChanged в ReadOnlyObservableCollection
Вы должны отличить коллекцию от INotifyCollectionChanged.
Почему ReadOnlyObservableCollection.CollectionChanged
защищен и не является общедоступным (в качестве соответствующего ObservableCollection.CollectionChanged
)?
Что такое использование коллекции, реализующей INotifyCollectionChanged
, если я не могу получить доступ к событию CollectionChanged
?
Здесь решение: События CollectionChanged в ReadOnlyObservableCollection
Вы должны отличить коллекцию от INotifyCollectionChanged.
Я нашел способ для вас, как это сделать:
ObservableCollection<string> obsCollection = new ObservableCollection<string>();
INotifyCollectionChanged collection = new ReadOnlyObservableCollection<string>(obsCollection);
collection.CollectionChanged += new NotifyCollectionChangedEventHandler(collection_CollectionChanged);
Вам просто нужно явно ссылаться на вашу коллекцию с помощью интерфейса INotifyCollectionChanged.
Вы можете проголосовать за запись об ошибке в Microsoft Connect, которая описывает эту проблему: https://connect.microsoft.com/VisualStudio/feedback/details/641395/readonlyobservablecollection-t-collectionchanged-event-should-be-public
Есть определенно веские причины для того, чтобы подписаться на сбор измененных уведомлений на ReadOnlyObservableCollection. Таким образом, в качестве альтернативы простое использование вашей коллекции как INotifyCollectionChanged, если вы являетесь подклассом ReadOnlyObservableCollection, то следующее предоставляет более синтаксически удобный способ доступа к a Событие CollectionChanged:
public class ReadOnlyObservableCollectionWithCollectionChangeNotifications<T> : ReadOnlyObservableCollection<T>
{
public ReadOnlyObservableCollectionWithCollectionChangeNotifications(ObservableCollection<T> list)
: base(list)
{
}
event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged2
{
add { CollectionChanged += value; }
remove { CollectionChanged -= value; }
}
}
Это сработало для меня раньше.
Я знаю, что этот пост старый, однако люди должны потратить свое время, чтобы понять шаблоны, используемые в .NET перед комментированием. Коллекция только для чтения является оболочкой существующей коллекции, которая запрещает пользователям изменять ее напрямую, посмотрите ReadOnlyCollection
, и вы увидите, что она является оберткой на IList<T>
, которая может быть или не быть изменчивой. Неизменяемые коллекции - это другое дело и охватываются новой неизменной коллекцией коллекций
Другими словами, чтение только не является неизменным!!!!
В стороне, ReadOnlyObservableCollection
должен неявно реализовать INotifyCollectionChanged
.
Это был лучший хит в Google, поэтому я решил, что добавлю свое решение в случае, если другие люди просмотрят его.
Используя приведенную выше информацию (о необходимости приведения к INotifyCollectionChanged), я сделал два метода расширения для регистрации и отмены регистрации.
Мое решение - методы расширения
public static void RegisterCollectionChanged(this INotifyCollectionChanged collection, NotifyCollectionChangedEventHandler handler)
{
collection.CollectionChanged += handler;
}
public static void UnregisterCollectionChanged(this INotifyCollectionChanged collection, NotifyCollectionChangedEventHandler handler)
{
collection.CollectionChanged -= handler;
}
Пример
IThing.cs
public interface IThing
{
string Name { get; }
ReadOnlyObservableCollection<int> Values { get; }
}
Использование методов расширения
public void AddThing(IThing thing)
{
//...
thing.Values.RegisterCollectionChanged(this.HandleThingCollectionChanged);
}
public void RemoveThing(IThing thing)
{
//...
thing.Values.UnregisterCollectionChanged(this.HandleThingCollectionChanged);
}
Решение OP
public void AddThing(IThing thing)
{
//...
INotifyCollectionChanged thingCollection = thing.Values;
thingCollection.CollectionChanged += this.HandleThingCollectionChanged;
}
public void RemoveThing(IThing thing)
{
//...
INotifyCollectionChanged thingCollection = thing.Values;
thingCollection.CollectionChanged -= this.HandleThingCollectionChanged;
}
Альтернатива 2
public void AddThing(IThing thing)
{
//...
(thing.Values as INotifyCollectionChanged).CollectionChanged += this.HandleThingCollectionChanged;
}
public void RemoveThing(IThing thing)
{
//...
(thing.Values as INotifyCollectionChanged).CollectionChanged -= this.HandleThingCollectionChanged;
}