Was ich habe, ist ein Objekt, das eine IsReadOnly
Eigenschaft hat. Wenn diese Eigenschaft wahr ist, möchte ich die IsEnabled
Eigenschaft für eine Schaltfläche (zum Beispiel) auf falsch setzen.
Ich würde gerne glauben, dass ich es so einfach machen kann, IsEnabled="{Binding Path=!IsReadOnly}"
aber das fliegt nicht mit WPF.
Muss ich alle Stileinstellungen durchlaufen? Scheint einfach zu wortreich für etwas so Einfaches wie das Setzen eines Bools auf die Umkehrung eines anderen Bools.
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
Antworten:
Sie können einen ValueConverter verwenden, der eine bool-Eigenschaft für Sie invertiert.
XAML:
Konverter:
quelle
!
ist das ein langwieriger Code ... Die Leute geben sich wahnsinnig viel Mühe, um das, was sie für "Code" halten, von diesen armen Designern zu trennen. Besonders schmerzhaft, wenn ich sowohl Programmierer als auch Designer bin.Haben Sie eine
IsNotReadOnly
Immobilie in Betracht gezogen ? Wenn das zu bindende Objekt ein ViewModel in einer MVVM-Domäne ist, ist die zusätzliche Eigenschaft durchaus sinnvoll. Wenn es sich um ein direktes Entitätsmodell handelt, können Sie die Komposition in Betracht ziehen und dem Formular ein spezielles ViewModel Ihrer Entität präsentieren.quelle
Bei Standardbindung müssen Sie Konverter verwenden, die wenig windig aussehen. Ich empfehle Ihnen daher, sich mein Projekt CalcBinding anzusehen , das speziell zur Lösung dieses und einiger anderer Probleme entwickelt wurde. Mit der erweiterten Bindung können Sie Ausdrücke mit vielen Quelleneigenschaften direkt in xaml schreiben. Sagen Sie, Sie können so etwas schreiben wie:
oder
oder
oder
Dabei sind A, B, C, IsChecked - Eigenschaften von viewModel und es wird ordnungsgemäß funktionieren
quelle
<Setter.Value><cb:Binding Path="!IsReadOnly" /></Setter.Value>
erhält eine 'Bindung' ist nicht gültig für Setter.Value 'KompilierungszeitfehlerIch würde empfehlen, https://quickconverter.codeplex.com/ zu verwenden.
Das Invertieren eines Booleschen Werts ist dann so einfach wie:
<Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />
Dies beschleunigt die normalerweise zum Schreiben von Konvertern benötigte Zeit.
quelle
Ich wollte, dass meine XAML so elegant wie möglich bleibt, also habe ich eine Klasse erstellt, um den Bool zu verpacken, der sich in einer meiner gemeinsam genutzten Bibliotheken befindet. Die impliziten Operatoren ermöglichen die nahtlose Verwendung der Klasse als Bool in CodeBehind
Die einzigen Änderungen, die an Ihrem Projekt erforderlich sind, bestehen darin, dass die Eigenschaft, die Sie invertieren möchten, diese anstelle von bool zurückgibt
Und im XAML-Postfix die Bindung entweder mit Value oder Invert
quelle
bool
Typausdrücken / Variablen verglichen / zugewiesen hat, auch wenn er nicht auf den inversen Wert verweist. Ich würde stattdessen eine "Nicht" -Erweiterungsmethode hinzufügenBoolean
Struct
.Property
vs.Method
fürBinding
. Meine "Downside" -Aussage gilt weiterhin. Übrigens ist die "Boolesche" "Nicht" -Erweiterungsmethode immer noch nützlich, um das "!" Operator, der leicht übersehen wird, wenn er (wie so oft) neben Zeichen eingebettet ist, die so aussehen (dh ein / mehrere "(" und "l" und "ich").Dieser funktioniert auch für nullfähige Bools.
quelle
Fügen Sie Ihrem Ansichtsmodell eine weitere Eigenschaft hinzu, die den umgekehrten Wert zurückgibt. Und binde das an den Knopf. Mögen;
im Ansichtsmodell:
in xaml:
quelle
Ich weiß nicht, ob dies für XAML relevant ist, aber in meiner einfachen Windows-App habe ich die Bindung manuell erstellt und einen Format-Ereignishandler hinzugefügt.
quelle
Format
undParse
Ereignisse in WinForms-Bindungen entsprechen in etwa dem WPF-Konverter.Ich hatte ein Inversionsproblem, aber eine ordentliche Lösung.
Die Motivation war, dass der XAML-Designer ein leeres Steuerelement anzeigt, z. B. wenn kein Datenkontext / no
MyValues
(itemssource) vorhanden ist.Anfangscode: Steuerung ausblenden , wenn sie
MyValues
leer ist. Verbesserte Code: Show Kontrolle , wennMyValues
nicht null oder leer.Das Problem ist natürlich, wie man "1 oder mehr Elemente" ausdrückt, was das Gegenteil von 0 Elementen ist.
Ich habe es gelöst, indem ich hinzugefügt habe:
Ergo wird die Standardeinstellung für die Bindung festgelegt. Natürlich funktioniert dies nicht bei allen Arten von inversen Problemen, hat mir aber mit sauberem Code geholfen.
quelle
💡 .Net Core Solution 💡
Behandelt die Nullsituation und löst keine Ausnahme aus, gibt jedoch zurück,
true
wenn kein Wert angezeigt wird. Andernfalls wird der eingegebene Boolesche Wert verwendet und umgekehrt.Xaml
App.Xaml Ich möchte alle meine Konverterstatiken in die Datei app.xaml einfügen, damit ich sie nicht in den Fenstern / Seiten / Steuerelementen des Projekts neu deklarieren muss.
Klar
converters:
ist der Namespace zur eigentlichen Klassenimplementierung (xmlns:converters="clr-namespace:ProvingGround.Converters"
).quelle
Nach der Antwort von @ Paul habe ich Folgendes im ViewModel geschrieben:
Ich hoffe, dass ein Ausschnitt hier jemandem hilft, wahrscheinlich Neuling wie ich.
Und wenn es einen Fehler gibt, lassen Sie es mich bitte wissen!
Übrigens stimme ich auch dem Kommentar von @heltonbiker zu - es ist definitiv der richtige Ansatz, nur wenn Sie ihn nicht mehr als dreimal verwenden müssen ...
quelle
Ich habe etwas sehr ähnliches gemacht. Ich habe meine Eigenschaft hinter den Kulissen erstellt, die die Auswahl einer Combobox NUR ermöglichte, wenn die Suche nach Daten abgeschlossen war. Wenn mein Fenster zum ersten Mal angezeigt wird, wird ein asynchron geladener Befehl gestartet, aber ich möchte nicht, dass der Benutzer auf die Combobox klickt, während noch Daten geladen werden (wäre leer und würde dann ausgefüllt). Standardmäßig ist die Eigenschaft also falsch, daher gebe ich die Umkehrung im Getter zurück. Wenn ich dann suche, setze ich die Eigenschaft auf true und nach Abschluss wieder auf false.
Dann kann ich die Combobox direkt an IsSearching binden:
quelle
Ich benutze einen ähnlichen Ansatz wie @Ofaim
quelle