Ce que j'ai, c'est un objet qui a une IsReadOnly
propriété. Si cette propriété est vraie, je voudrais définir la IsEnabled
propriété d'un bouton (par exemple) sur false.
Je voudrais croire que je peux le faire aussi facilement que cela, IsEnabled="{Binding Path=!IsReadOnly}"
mais cela ne fonctionne pas avec WPF.
Suis-je relégué à devoir passer par tous les paramètres de style? Cela semble trop verbeux pour quelque chose d'aussi simple que de mettre un booléen à l'inverse d'un autre booléen.
<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>
Réponses:
Vous pouvez utiliser un ValueConverter qui inverse une propriété booléenne pour vous.
XAML:
Convertisseur:
la source
!
, c'est un code de longue haleine ... Les gens font des efforts fous pour séparer ce qu'ils pensent être du "code" de ces pauvres concepteurs. Extra extra douloureux quand je suis à la fois codeur et designer.Avez-vous envisagé une
IsNotReadOnly
propriété? Si l'objet lié est un ViewModel dans un domaine MVVM, la propriété supplémentaire est parfaitement logique. S'il s'agit d'un modèle d'entité direct, vous pouvez envisager la composition et la présentation d'un ViewModel spécialisé de votre entité au formulaire.la source
Avec la reliure standard, vous devez utiliser des convertisseurs qui semblent peu venteux. Donc, je vous recommande de regarder mon projet CalcBinding , qui a été développé spécialement pour résoudre ce problème et quelques autres. Avec la liaison avancée, vous pouvez écrire des expressions avec de nombreuses propriétés source directement dans xaml. Dites, vous pouvez écrire quelque chose comme:
ou
ou
ou
où A, B, C, IsChecked - propriétés de viewModel et cela fonctionnera correctement
la source
<Setter.Value><cb:Binding Path="!IsReadOnly" /></Setter.Value>
obtient une 'liaison' n'est pas valide pour Setter.Value 'erreur de compilationJe recommanderais d'utiliser https://quickconverter.codeplex.com/
Inverser un booléen est alors aussi simple que:
<Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />
Cela accélère le temps normalement nécessaire pour écrire des convertisseurs.
la source
Je voulais que mon XAML reste aussi élégant que possible, j'ai donc créé une classe pour envelopper le bool qui réside dans l'une de mes bibliothèques partagées, les opérateurs implicites permettent à la classe d'être utilisée comme bool dans le code-behind de manière transparente
Les seules modifications nécessaires à votre projet sont de faire en sorte que la propriété que vous souhaitez inverser renvoie ceci au lieu de bool
Et dans le suffixe XAML, la liaison avec Value ou Invert
la source
bool
expressions / variables de type, même sans référencer la valeur inverse. J'ajouterais à la place une méthode d'extension "Non" à laBoolean
Struct
.Property
contreMethod
pourBinding
. Ma déclaration de «inconvénient» s'applique toujours. Btw, la méthode d'extension «non» «booléenne» est toujours utile pour éviter le «!» Opérateur qui est facilement manqué quand il (comme c'est souvent le cas) est intégré à côté des caractères qui lui ressemblent (c.-à-d. Un / plusieurs "(" et "l" et "je"))Celui-ci fonctionne également pour les bools nullables.
la source
Ajoutez une propriété de plus dans votre modèle de vue, qui renverra la valeur inverse. Et liez ça au bouton. Comme;
en vue modèle:
en xaml:
la source
Je ne sais pas si cela est pertinent pour XAML, mais dans ma simple application Windows, j'ai créé la liaison manuellement et ajouté un gestionnaire d'événements Format.
la source
Format
et lesParse
événements dans les liaisons WinForms sont à peu près équivalents au convertisseur WPF.J'ai eu un problème d'inversion, mais une bonne solution.
La motivation était que le concepteur XAML afficherait un contrôle vide, par exemple lorsqu'il n'y avait pas de datacontext / no
MyValues
(itemssource).Code initial: masquer le contrôle lorsqu'il
MyValues
est vide. Code amélioré: affichez le contrôle quand ilMyValues
n'est PAS nul ou vide.Bien entendu, le problème est de savoir comment exprimer «1 ou plusieurs éléments», ce qui est l'opposé de 0 élément.
Je l'ai résolu en ajoutant:
Ergo définissant la valeur par défaut pour la liaison. Bien sûr, cela ne fonctionne pas pour toutes sortes de problèmes inverses, mais cela m'a aidé avec du code propre.
la source
💡 .Net Core Solution 💡
Gère une situation nulle et ne renvoie pas d'exception, mais retourne
true
si aucune valeur n'est présentée; sinon prend le booléen entré et l'inverse.Xaml
App.Xaml J'aime mettre toutes mes statistiques de convertisseur dans le fichier app.xaml donc je n'ai pas à les redéclarer dans les fenêtres / pages / contrôles du projet.
Pour être clair,
converters:
c'est l'espace de noms de l'implémentation de classe réelle (xmlns:converters="clr-namespace:ProvingGround.Converters"
).la source
Suite à la réponse de @ Paul, j'ai écrit ce qui suit dans le ViewModel:
J'espère qu'avoir un extrait ici aidera quelqu'un, probablement un débutant comme moi.
Et s'il y a une erreur, faites-le moi savoir!
BTW, je suis également d'accord avec le commentaire de @heltonbiker - c'est certainement l'approche correcte uniquement si vous n'avez pas à l'utiliser plus de 3 fois ...
la source
J'ai fait quelque chose de très similaire. J'ai créé ma propriété dans les coulisses qui a permis la sélection d'une zone de liste déroulante UNIQUEMENT si elle avait fini de rechercher des données. Lorsque ma fenêtre apparaît pour la première fois, elle lance une commande chargée asynchrone mais je ne veux pas que l'utilisateur clique sur la zone de liste déroulante pendant le chargement des données (serait vide, puis renseignée). Donc, par défaut, la propriété est fausse, je renvoie donc l'inverse dans le getter. Ensuite, lorsque je recherche, je définis la propriété sur true et de nouveau sur false une fois terminé.
Ensuite, pour la zone de liste déroulante, je peux le lier directement à IsSearching:
la source
J'utilise une approche similaire comme @Ofaim
la source