Warum ist ReadOnlyObservableCollection.CollectionChanged
geschützt und nicht öffentlich (wie das entsprechende ObservableCollection.CollectionChanged
ist)?
Was nützt eine implementierte Sammlung, INotifyCollectionChanged
wenn ich nicht auf das CollectionChanged
Ereignis zugreifen kann ?
c#
.net
collections
Oskar
quelle
quelle
Antworten:
Hier ist die Lösung: CollectionChanged-Ereignisse in ReadOnlyObservableCollection
Sie müssen werfen , die Sammlung zu INotifyCollectionChanged .
quelle
Ich habe einen Weg für Sie gefunden, wie das geht:
Sie müssen nur explizit über die INotifyCollectionChanged- Schnittstelle auf Ihre Sammlung verweisen .
quelle
ReadOnlyObservableCollection
Ihnen durchsuchen, finden Sie Folgendes :event NotifyCollectionChangedEventHandler INotifyCollectionChanged.CollectionChanged
. Explizite Schnittstellenimplementierung des Ereignisses.Ich weiß, dass dieser Beitrag alt ist, aber die Leute sollten sich Zeit nehmen, um die in .NET verwendeten Muster zu verstehen, bevor sie Kommentare abgeben. Eine schreibgeschützte Sammlung ist ein Wrapper für eine vorhandene Sammlung, der verhindert, dass Verbraucher sie direkt ändern. Sehen
ReadOnlyCollection
Sie sich an, und Sie werden sehen, dass es sich um einen Wrapper handelt,IList<T>
der möglicherweise veränderbar ist oder nicht. Unveränderliche Sammlungen sind eine andere Sache und werden von der neuen Bibliothek unveränderlicher Sammlungen abgedecktMit anderen Worten, schreibgeschützt ist nicht dasselbe wie unveränderlich !!!!
Davon abgesehen
ReadOnlyObservableCollection
sollte implizit umgesetzt werdenINotifyCollectionChanged
.quelle
Es gibt definitiv gute Gründe, Benachrichtigungen über geänderte Sammlungen in einer ReadOnlyObservableCollection abonnieren zu wollen . So, als Alternative zu lediglich Ihrer Sammlung als Casting INotifyCollectionChanged , wenn Sie geschehen , werden Subklassen ReadOnlyObservableCollection , dann bietet die folgenden eine syntaktisch bequeme Möglichkeit , die einen Zugriff auf Collection Ereignis:
Das hat bei mir schon mal gut geklappt.
quelle
Sie können für den Fehlereintrag in Microsoft Connect stimmen, der dieses Problem beschreibt: https://connect.microsoft.com/VisualStudio/feedback/details/641395/readonlyobservablecollection-t-collectionchanged-event-should-be-public
Aktualisieren:
Das Connect-Portal wurde von Microsoft heruntergefahren. Der obige Link funktioniert also nicht mehr.
Meine WAF-Bibliothek (Win Application Framework) bietet eine Lösung: ReadOnlyObservableList- Klasse:
quelle
Wie bereits beantwortet, haben Sie zwei Möglichkeiten: Sie können entweder
ReadOnlyObservableCollection<T>
die Schnittstelle in die Schnittstelle umwandeln,INotifyCollectionChanged
um auf das explizit implementierteCollectionChanged
Ereignis zuzugreifen , oder Sie können eine eigene Wrapper-Klasse erstellen, die dies einmal im Konstruktor ausführt und nur die Ereignisse des Wraps verknüpftReadOnlyObservableCollection<T>
.Einige zusätzliche Einblicke, warum dieses Problem noch nicht behoben wurde:
Wie Sie dem Quellcode entnehmen können ,
ReadOnlyObservableCollection<T>
handelt es sich um eine öffentliche, nicht versiegelte (dh vererbbare) Klasse, in der die Ereignisse markiert sindprotected virtual
.Das heißt, es gibt möglicherweise kompilierte Programme mit Klassen, von denen abgeleitet wurde
ReadOnlyObservableCollection<T>
, mit überschriebenen Ereignisdefinitionen, aberprotected
Sichtbarkeit. Diese Programme würden ungültigen Code enthalten, sobald diepublic
Sichtbarkeit des Ereignisses in der Basisklasse geändert wird , da die Sichtbarkeit eines Ereignisses in abgeleiteten Klassen nicht eingeschränkt werden darf.Leider ist das spätere Erstellen von
protected virtual
Ereignissenpublic
eine binäre Änderung, und daher wird dies nicht ohne sehr gute Argumentation geschehen, was ich befürchte, "Ich muss das Objekt einmal umsetzen, um Handler anzuhängen", einfach nicht.Quelle: GitHub-Kommentar von Nick Guererra, 19. August 2015
quelle
Dies war der Top-Hit bei Google, also dachte ich mir, ich würde meine Lösung hinzufügen, falls andere Leute dies nachschlagen.
Unter Verwendung der obigen Informationen (über die Notwendigkeit, in INotifyCollectionChanged umzuwandeln ) habe ich zwei Erweiterungsmethoden zum Registrieren und Aufheben der Registrierung erstellt.
Meine Lösung - Erweiterungsmethoden
Beispiel
IThing.cs
Verwenden der Erweiterungsmethoden
OPs Lösung
Alternative 2
quelle