Ich möchte ein ViewModel schreiben, das immer den aktuellen Status einiger schreibgeschützter Abhängigkeitseigenschaften aus der Ansicht kennt.
Insbesondere enthält meine GUI einen FlowDocumentPageViewer, der jeweils eine Seite aus einem FlowDocument anzeigt. FlowDocumentPageViewer stellt zwei schreibgeschützte Abhängigkeitseigenschaften mit den Namen CanGoToPreviousPage und CanGoToNextPage bereit. Ich möchte, dass mein ViewModel immer die Werte dieser beiden View-Eigenschaften kennt.
Ich dachte, ich könnte dies mit einer OneWayToSource-Datenbindung tun:
<FlowDocumentPageViewer
CanGoToNextPage="{Binding NextPageAvailable, Mode=OneWayToSource}" ...>
Wenn dies zulässig wäre, wäre es perfekt: Wenn sich die CanGoToNextPage-Eigenschaft von FlowDocumentPageViewer ändert, wird der neue Wert in die NextPageAvailable-Eigenschaft von ViewModel verschoben, genau das, was ich möchte.
Leider wird dies nicht kompiliert: Ich erhalte die Fehlermeldung, dass die Eigenschaft 'CanGoToPreviousPage' schreibgeschützt ist und nicht über das Markup festgelegt werden kann. Offenbar schreibgeschützte Eigenschaften nicht unterstützen jede Art von Datenbindung, nicht einmal , dass die Datenbindung schreibgeschützt in Bezug auf diese Eigenschaft.
Ich könnte festlegen, dass die Eigenschaften meines ViewModels DependencyProperties sind, und eine OneWay-Bindung in die andere Richtung erstellen, aber ich bin nicht verrückt nach der Verletzung der Trennung von Bedenken (ViewModel würde einen Verweis auf die Ansicht benötigen, den die MVVM-Datenbindung vermeiden soll ).
FlowDocumentPageViewer macht kein CanGoToNextPageChanged-Ereignis verfügbar, und ich kenne keine gute Möglichkeit, Änderungsbenachrichtigungen von einer DependencyProperty abzurufen, ohne eine andere DependencyProperty zu erstellen, an die sie gebunden werden kann, was hier wie ein Overkill erscheint.
Wie kann ich mein ViewModel über Änderungen an den schreibgeschützten Eigenschaften der Ansicht auf dem Laufenden halten?
quelle
Size
Eigenschaft zu erstellen , die Höhe und Breite kombiniert. Ca. 50% weniger Code.ActualSize
Eigenschaft in gibtFrameworkElement
. Wenn Sie direkt wollen die angefügten Eigenschaften zu binden, müssen Sie zwei Eigenschaften erstellen , um gebunden zu seinActualWidth
undActualHeight
jeweils.Ich verwende eine universelle Lösung, die nicht nur mit ActualWidth und ActualHeight funktioniert, sondern auch mit allen Daten, an die Sie zumindest im Lesemodus binden können.
Das Markup sieht folgendermaßen aus, sofern ViewportWidth und ViewportHeight Eigenschaften des Ansichtsmodells sind
Hier ist der Quellcode für die benutzerdefinierten Elemente
quelle
Target
Eigenschaft beschreibbar gemacht werden muss, obwohl sie nicht von außen geändert werden darf: - /Wenn jemand anderes interessiert ist, habe ich hier eine Annäherung an Kents Lösung codiert:
Fühlen Sie sich frei, es in Ihren Apps zu verwenden. Es funktioniert gut. (Danke Kent!)
quelle
Hier ist eine weitere Lösung für diesen "Fehler", über den ich hier gebloggt habe :
OneWayToSource-Bindung für ReadOnly-Abhängigkeitseigenschaft
Es funktioniert mit zwei Abhängigkeitseigenschaften, Listener und Mirror. Der Listener ist OneWay an die TargetProperty gebunden und aktualisiert im PropertyChangedCallback die Mirror-Eigenschaft, die OneWayToSource an die in der Bindung angegebenen Werte bindet. Ich nenne es
PushBinding
und es kann für jede schreibgeschützte Abhängigkeitseigenschaft wie diese festgelegt werdenLaden Sie hier das Demo-Projekt herunter .
Es enthält Quellcode und kurze Beispielnutzung oder besuchen Sie meinen WPF-Blog, wenn Sie an den Implementierungsdetails interessiert sind.
Ein letzter Hinweis: Seit .NET 4.0 sind wir noch weiter von der integrierten Unterstützung entfernt, da eine OneWayToSource-Bindung den Wert aus der Quelle zurückliest, nachdem sie aktualisiert wurde
quelle
Ich mag die Lösung von Dmitry Tashkinov! Allerdings stürzte mein VS im Designmodus ab. Aus diesem Grund habe ich der OnSourceChanged-Methode eine Zeile hinzugefügt:
quelle
Ich denke, es kann ein bisschen einfacher gemacht werden:
xaml:
cs:
quelle