ObservableCollection PropertyChanged-Ereignis

8

OK, also möchte ich ObservableCollection ableiten, um eine Eigenschaft hinzuzufügen. Leider ist das PropertyChanged Event geschützt. Im Grunde genommen möchte ich eine Unterklasse erstellen, die eine SelectedItem enthält, an die ich für Listen in meiner MVVM WPF-App binden kann.

Hier ist das Skelett meiner Klasse:

%Vor%

Aber ich kann Folgendes nicht tun:

%Vor%

wegen Zugriffsbeschränkungen. Das veranlasst mich, eine tiefere Frage zu stellen. Wie kann die Benutzeroberfläche von PropertyChanged -Ereignissen (z. B. Count-Eigenschaft) benachrichtigt werden, und ich kann es nicht in Code-Behind tun?

Mein Kopf dreht sich, kann jemand bitte mich erleuchten?

    
Jose 16.06.2009, 18:58
quelle

4 Antworten

10
%Vor%

ObservableCollection implementiert INotifyPropertyChanged explizit , was bedeutet, dass Sie um die Instanz auf die Schnittstelle zu übertragen, bevor Sie auf die Methoden, Eigenschaften und Ereignisse der Schnittstelle zugreifen können. Warum das gemacht wird, weiß ich nicht. Die Binding-Markup-Erweiterung kennt ObservableCollections oder andere nicht anderer Typ. Es überprüft Typen, ob sie bestimmte Schnittstellen / Basisklassen (INPC, INCC, DependencyObject usw.) implementieren oder erweitern, und es ist daher egal, ob die Schnittstelle explizit implementiert wird.

    
Will 16.06.2009, 19:14
quelle
8

ObservableCollection (int .NET 3.5) scheint das PropertyChanged-Ereignis in einem interessanter Weg .

%Vor%

Dies bedeutet, dass das geschützte Ereignis PropertyChanged wahrscheinlich nur für die interne Implementierung gedacht ist. Das andere INotifyPropertyChanged.PropertyChanged -Ereignis ist dasjenige, das die Implementierung der INotifyPropertyChanged -Schnittstelle tatsächlich als explizite Schnittstelle . Seltsamerweise sehe ich keinen Platz innerhalb der ObservableCollection, in dem INotifyPropertyChanged.PropertyChanged tatsächlich ausgelöst wird. Dies könnte bedeuten, dass dies ein Fehler in .NET 3.5 war, obwohl ich nicht getestet habe, um zu bestätigen, ob zum Beispiel ein Eigenschaft geändertes Ereignis für Count ausgelöst wird, wenn ein Element zu einer Sammlung hinzugefügt wird, aber scheinbar so ist, wie es funktionieren soll .

In der .NET 4.0-Implementierung scheint das INotifyPropertyChanged.PropertyChanged -Ereignis stattdessen an denselben privaten Delegaten gebunden zu sein, der vom geschützten PropertyChanged -Ereignis verwendet wird, das möglicherweise ein Fehler war Fix. Es ist auch möglich, dass dies nur wegen Unterschiede bei der Behandlung von Auto-Event-Implementierungen in .NET 4.0 .

Korrektur: Ich habe überprüft, dass das INotifyPropertyChanged.PropertyChanged -Ereignis von ObservableCollection ausgelöst wird. Daher basieren die oben gemachten Annahmen auf der Verwendung von Reflector zur Betrachtung der ObservableCollection-Implementierung muss ungenau sein. Meine Vermutung ist, dass der Reflektor etwas seltsames tut. Ich habe noch keinen Beweis dafür.

Um Ihr Beispiel zur Arbeit zu bringen, müßten Sie schreiben, damit das funktioniert. Es würde wie das folgende Beispiel aussehen, wie Will es in seiner Antwort gezeigt hat.

%Vor%

Interessant, oder? Die Verwendung von expliziten Schnittstellen wird hauptsächlich verwendet, um unvermeidliche Kollisionen in Mitgliedern zu vermeiden, die für eine gegebene Schnittstelle erforderlich sind, aber sie können dazu verwendet werden, in gewisser Weise die Existenz eines Mitglieds zu verbergen.

Wenn Sie Eigenschaftsänderungsereignisse für Ihre eigenen angepassten Eigenschaften, die Sie in Ihrer Unterklasse einführen, erhöhen möchten, müssen Sie die geschützte OnPropertyChanged -Methode überschreiben, die ebenfalls von ObservableCollection implementiert wird. Diese Technik ist ein gut angenommener Standard und ermöglicht es Unterklassen, Ereignisse auszulösen oder Ereignisse zu handhaben, ohne Zugriff auf den zugrunde liegenden Ereignisdelegaten zu haben. Es wird im Allgemeinen bevorzugt, diese Technik übrigens auch zu verwenden, statt eine Unterklasse Hook-Event-Handler für ihre eigenen Basisklassen-Events zu haben. Sehen Sie sich für weitere Beispiele an, wie Ereignisse in verschiedenen Steuerelementen in WinForms und WPF implementiert werden.

    
jpierson 29.03.2011 20:59
quelle
1

Ich habe versucht, eine neue Eigenschaft in

hinzuzufügen %Vor%

Ich habe wirklich nicht bemerkt, dass PropertyChanged als protected definiert ist. Schließlich wurde die Val-Eigenschaft in ViewModel verschoben.

    
Somnath 28.12.2012 06:23
quelle
0

Die Benutzeroberfläche kann und wird benachrichtigt. Dies ist eine Einschränkung JUST mit ObservableCollection, die das PropertyChanged-Ereignis als protected definiert.

FWIW, ich denke, Sie sollten ObservableCollection lieber allein lassen und nur eine weitere Eigenschaft zu Ihrer VM hinzufügen.

    
micahtan 16.06.2009 19:16
quelle