Hallo zusammen,
Ich habe eine Combobox, die je nach Auswahl einer andern Combobox disabled oder enabled sein soll.
<DatePicker Grid.Row="3" Grid.Column="1" SelectedDate="{Binding RangeEndTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding IsEventDurationEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" FontWeight="Bold" HorizontalAlignment="Left"
VerticalAlignment="Center" Width="100" Margin="2.5"/>
Da sonst alle PropertyChangedEvents abgeholt werden, stehe ich völig auf dem Schlauch.
Der Code des PropertyChangedEvents ist;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(typeof(T), new PropertyChangedEventArgs(propertyName));
}
Blickt da jemand durch?
Gruss Alex
vielleicht stimmt der angegebene propertyName nicht
Der frühe Apfel fängt den Wurm.
Ich invoke so einen Event immer mit this
(also der Referenz von der Instanz die den Event auslöst) und nicht mit dem Type von (ähh, ja von welchem überhaupt).
PS So eine Event-Raiser Methode sollte immer als protected virtual
deklariert werden. Erleichtert oft das Leben ;o)
Wieso invokest du mit einem Typ als sender?
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
Wieso invokest du mit einem Typ als sender?
Der void ist eigntlich protected und befindet sich in einer generischen Basisklasse für alle Views, der ich ten Typ der abgeleiteten Klasse mitgebe.
Gruss Alex
Hallo,
also mit dem Typen kann es nicht funktionieren. Du brauchst auf jeden Fall das konkrete Objekt als sender.
Stell Dir einfach mal vor, Du hast mehrere Deiner VM-Objekte in verschiedenen Views, eines davon ändert sich, das andere nicht. Wie soll denn über den Typen entschieden werden, welche View dann aktualisiert werden soll?
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Hallo MarsStein,
Ich denke nicht, dass die übergabe mit typeof(T) den Fehler verursacht, da sont auch alle PropertyChangedEvents nicht abgehohlt würden. Dies ist jedoch der in allen Datenrelevanten Properties der fall, also muss meines erachtens dies keine Rolle spielen.
Gruss Alex
Dann binde doch einfach mal an eine Property, bei der es geht (ggf. mit Converter zwischen) - um sicherzustellen, ob da überhaupt was ankommt bzw. das IsEnabled funktioniert.
Und schaue in das Output, ob du Binding-Fehler hast.
Und zeige mal deine Property IsEventDurationEnabled
.
Hallo,
möglicherweise funktionieren Deine Properties auch mit dem Typen. Da würde ich mich aber jedenfalls nicht drauf verlassen - Gründe stehen oben.
Das Event wird ja von Framework-Klassen konsumiert, und nicht von Dir selbst. Da könnte es dann fallweise implementierungsabhängig sein, ob und wie die Events konsumiert werden.
Früher stand das als Konvention explizit in der Doku:
Raising an Event
By convention, events in the .NET Framework have the signature EventName(sender, e), where sender is an Object that provides a reference to the class or structure that fired the event
Der Artikel wurde allerdings überarbeitert, und diese Konvention ist nicht mehr explizit genannt.
Andere Sache, von der ich aber nicht glaube, dass sie Dein Problem auslöst:
Mode=OneWay
und UpdateSourceTrigger
passen nicht wirklich zusammen.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Hi Maendler,
Wieso invokest du mit einem Typ als sender?
Der void ist eigntlich protected und befindet sich in einer generischen Basisklasse für alle Views, der ich ten Typ der abgeleiteten Klasse mitgebe.
Das klingt aber sehr abenteuerlich... Eine Basisklasse, die den Typ der konkreten Implementierung als Typ-Parameter übergeben bekommt? Wozu soll das gut sein?
Und unabhängig davon sollte es trotzdem heißen:
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Weeks of programming can save you hours of planning
Hallo,
ich habe mir jetzt mal angesehen, was da eigentlich im Hintergrund passiert:
WPF benutzt den PropertyChangedEventManager, einen spezialisierten WeakEventManager, um auf die PropertyChanged Events des VM zu reagieren.
Ich beziehe mich im Folgenden auf die Codezeilen aus der verlinkten Quelle.
Irgendwann wird die AddListener
-Methode (276) aufgerufen, diese ordnet dem _Quellobjekt _(dem VM oder genauer: dem Source-Objekt des Bindings) ein Dictionary zu (287), in dem zum gewünschten Propertynamen - der ja über das Binding bekannt ist - eine Liste mit den benötigten Handlern gehalten wird.
Anschließend wird in (290) die Methode StartListening
(150) aufgerufen, welche das PropertyChanged-Event abonniert.
Der registrierte Handler findet sich ab (378). Dort wird zunächst versucht, das dem _Quellobjekt _(diesmal sender) zugeordnete Dictionary zu finden (387). Wird es nicht gefunden, wird eine leere Handlerliste benutzt (389-394), und damit bist Du aus der Nummer raus.
Genau das ist hier der Fall: Da der sender
der _Typ _und nicht das Quellobjekt ist, existiert auch kein Dictionary dazu, und es passiert nichts mehr weiter.
WPF bzw. der PropertyChangedEventManager
geht also sehr wohl davon aus, dass das Objekt als sender
übergeben wird, das die geänderte Property enthält. An einem kleinen einfachen Beispiel konnte ich das auch genau so nachvollziehen.
da sont auch alle PropertyChangedEvents nicht abgehohlt würden. Dies ist jedoch der in allen Datenrelevanten Properties der fall, also muss meines erachtens dies keine Rolle spielen.
Der oben gezeigte Mechanismus - sofern ich ihn richtig verstanden habe - verleitet mich dazu, das Gegenteil zu behaupten.
Das kann eigentlich nur funktionieren, wenn da ganze DataContext-Objekte ausgetauscht werden, oder ObservableCollections geändert werden, dann läuft das ganze wieder etwas anders. Die Gegenrichtung - Updaten des ViewModels aus der View - ist natürlich auch nicht betroffen.
Ich glaube, dass Du da einem Trugschluss aufgesessen bist. Die Bindings funktioneren zwar initial, Änderungsbenachrichtigungen direkt vom ViewModel über INPC kann die View aber auf diese Weise nicht erhalten.
Also tu Dir selbst den Gefallen und probier es einfach einmal aus, statt Dich auf Dein seltsames Konzept zu vesteifen - das funktioniert nämlich schlichtweg nicht.
Gruß, MarsStein
Edit: Typos
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca