Ich versuche, Readonly
mit OneWayToSource
as mode an eine Eigenschaft zu binden , aber es scheint, dass dies in XAML nicht möglich ist:
<controls:FlagThingy IsModified="{Binding FlagIsModified,
ElementName=container,
Mode=OneWayToSource}" />
Ich bekomme:
Die Eigenschaft 'FlagThingy.IsModified' kann nicht festgelegt werden, da sie keinen zugänglichen Set-Accessor hat.
IsModified
ist ein Readonly DependencyProperty
auf FlagThingy
. Ich möchte diesen Wert an die FlagIsModified
Eigenschaft im Container binden .
Deutlich sein:
FlagThingy.IsModified --> container.FlagIsModified
------ READONLY ----- ----- READWRITE --------
Ist dies nur mit XAML möglich?
Update: Nun, ich habe diesen Fall behoben, indem ich die Bindung für den Container und nicht für den Container festgelegt habe FlagThingy
. Aber ich würde immer noch gerne wissen, ob dies möglich ist.
wpf
data-binding
xaml
readonly
Inferis
quelle
quelle
IsModified
zur Eigenschaft readwrite zu gelangenFlagIsModified
.Antworten:
Einige Forschungsergebnisse für OneWayToSource ...
Option 1.
Option 2
Option 3 (Echte schreibgeschützte Abhängigkeitseigenschaft)
System.ArgumentException: Die Eigenschaft 'IsModified' kann nicht datengebunden werden.
Reflektor gibt die Antwort:
quelle
DependencyProperty
DP sein). Ein schreibgeschützter DP kann nur mit dem zugehörigen geändert werdenDependencyPropertyKey
. Um eine zu registrieren, mussBindingExpression
die Engine die Metadaten des Ziel-DP manipulieren. Da diesDependencyPropertyKey
als privat angesehen wird, um den öffentlichen Schreibschutz zu gewährleisten, muss die Engine diesen Schlüssel ignorieren, da die Bindung auf einem schreibgeschützten DP nicht registriert werden kann.Dies ist eine Einschränkung von WPF und beabsichtigt. Hier wird über Connect berichtet:
OneWayToSource-Bindung von einer schreibgeschützten Abhängigkeitseigenschaft
Ich habe eine Lösung gefunden, um schreibgeschützte Abhängigkeitseigenschaften dynamisch an die Quelle zu übertragen, über
PushBinding
die ich hier gebloggt habe . Das folgende Beispiel führtOneWayToSource
Bindungen von den schreibgeschützten DPsActualWidth
undActualHeight
zu den Eigenschaften Breite und Höhe derDataContext
PushBinding
funktioniert mit zwei Abhängigkeitseigenschaften, Listener und Mirror. Der Listener ist anOneWay
die TargetProperty gebunden undPropertyChangedCallback
aktualisiert darin die Mirror-Eigenschaft, die anOneWayToSource
die in der Bindung angegebenen Werte gebunden ist .Demo-Projekt kann hier heruntergeladen werden.
Es enthält Quellcode und kurze Beispielnutzung oder besuchen Sie meinen WPF-Blog, wenn Sie an den Implementierungsdetails interessiert sind.
quelle
Schrieb dies:
Verwendung:
Code:
Habe es noch nicht in Stilen und Vorlagen getestet, schätze, es braucht ein spezielles Gehäuse.
quelle
Hier ist eine weitere angehängte Eigenschaftslösung, die auf SizeObserver basiert. Hier wird beschrieben, wie schreibgeschützte GUI-Eigenschaften wieder in ViewModel verschoben werden
Deklarieren Sie die angehängte Eigenschaft unter Kontrolle
quelle
Hier ist eine weitere Implementierung zum Binden an Validation.HasError
Verwendung in xaml
Diese Implementierung ist bindungsspezifisch
Validation.HasError
quelle
WPF verwendet den CLR-Eigenschaftssetzer nicht, scheint jedoch eine seltsame Validierung basierend darauf durchzuführen.
Möglicherweise ist dies in Ihrer Situation in Ordnung:
quelle
Hmmm ... Ich bin mir nicht sicher, ob ich mit einer dieser Lösungen einverstanden bin. Wie wäre es, wenn Sie in Ihrer Immobilienregistrierung einen Zwangsrückruf angeben, der externe Änderungen ignoriert? Zum Beispiel musste ich eine schreibgeschützte Positionseigenschaftseigenschaft implementieren, um die Position eines MediaElement-Steuerelements innerhalb eines Benutzersteuerelements abzurufen. So habe ich es gemacht:
Mit anderen Worten, ignorieren Sie einfach die Änderung und geben Sie den Wert zurück, der von einem anderen Mitglied ohne öffentlichen Modifikator unterstützt wird. - Im obigen Beispiel ist MediaRenderer das private MediaElement-Steuerelement.
quelle
Die Art und Weise, wie ich diese Einschränkung umging, bestand darin, nur eine Bindungseigenschaft in meiner Klasse verfügbar zu machen und die DependencyProperty insgesamt privat zu halten. Ich habe eine schreibgeschützte Eigenschaft "PropertyBindingToSource" implementiert (dies ist keine DependencyProperty), die in der xaml auf einen verbindlichen Wert gesetzt werden kann. Im Setter für diese schreibgeschützte Eigenschaft rufe ich BindingOperations.SetBinding auf, um die Bindung mit der DependencyProperty zu verknüpfen.
Für das spezifische Beispiel des OP würde es so aussehen:
Die FlatThingy-Implementierung:
Beachten Sie, dass das statische schreibgeschützte DependencyProperty-Objekt privat ist. Im Steuerelement habe ich eine Schaltfläche hinzugefügt, deren Klick von Button_Click verarbeitet wird. Die Verwendung des FlatThingy-Steuerelements in meiner window.xaml:
Beachten Sie, dass ich auch ein ViewModel zum Binden implementiert habe, das hier nicht angezeigt wird. Es macht eine DependencyProperty mit dem Namen "FlagIsModified" verfügbar, wie Sie aus der obigen Quelle entnehmen können.
Es funktioniert hervorragend und ermöglicht es mir, Informationen aus der Ansicht lose gekoppelt in das ViewModel zurückzuschieben, wobei die Richtung dieses Informationsflusses explizit definiert ist.
quelle
Sie machen die Bindung gerade in die falsche Richtung. OneWayToSource versucht, FlagIsModified für Container zu aktualisieren, wenn IsModified Änderungen an dem von Ihnen erstellten Steuerelement ändert. Sie möchten das Gegenteil, nämlich IsModified an container.FlagIsModified binden. Dafür sollten Sie den Bindungsmodus OneWay verwenden
Vollständige Liste der Aufzählungsmitglieder: http://msdn.microsoft.com/en-us/library/system.windows.data.bindingmode.aspx
quelle
IsIsModified
, dass 2) das OP eine Bindung für diese Eigenschaft in XAML deklarieren möchte und dass 3) die Bindung imOneWayToSource
Modus funktionieren soll . Ihre Lösung funktioniert praktisch nicht, da Sie, wie in der Frage beschrieben, vom Compiler keine Bindung für eine schreibgeschützte Eigenschaft deklarieren können, und sie funktioniert konzeptionell nicht, da sieIsModified
schreibgeschützt ist und ihr Wert daher nicht sein kann geändert (durch die Bindung).