9
votes

Bouton Activer en fonction de la valeur de la zone de texte (WPF)

Ceci est une application MVVM. Il y a une fenêtre et une classe de modèle de vue connexe.

Il y a textbox code>, bouton code> et listbox code> sur le formulaire. Le bouton est lié à Délégatecommand code> qui a canexecute fonction code>. L'idée est que l'utilisateur entre dans certaines données dans la zone de texte, appuie sur la touche et les données sont ajoutées à la zone de liste. P>

Je souhaite activer la commande (et le bouton) lorsque l'utilisateur entre des données correctes dans Textbox code>. Les choses fonctionnent comme ceci maintenant: p>

  • canexecute () code> La méthode contient du code qui vérifie si les données dans la zone liée à la propriété sont correctes. LI>
  • La zone de texte est liée à la propriété dans la vue Modèle Li>
  • updatedatesRetretrigger code> est défini sur PropertyChanged "/ code> et propriété dans la vue du modèle est mis à jour après chaque touche Presses utilisateur. li> ul>

    problème est que canexecute () code> ne se déclenche pas lorsque l'utilisateur entre dans les données dans la zone de texte. Il ne tire pas même lorsque la zone de texte perd la mise au point. P>

    Comment pourrais-je faire ce travail? P>

    edit: strong>

    Commentaire de Re Yanko:

    La commande déléguée est implémentée dans MVVM Toolkit Modèle et lorsque vous créez un nouveau projet MVVM, il existe une commande déléguée en solution. Autant que j'ai vu dans des vidéos de prisme, cela devrait être la même classe (ou au moins très similaire). P>

    Voici XAML Snippet: P>

    /// <summary>
    /// This class facilitates associating a key binding in XAML markup to a command
    /// defined in a View Model by exposing a Command dependency property.
    /// The class derives from Freezable to work around a limitation in WPF when 
    /// databinding from XAML.
    /// </summary>
    
    • Setter Property pour ObjectName code> est déclenché sur chaque touches de Textbox Li>
    • Si je mets retour vrai; code> dans canadandObject () code>, la commande est active (bouton à) li> ul>

      Il me semble que la liaison est correcte. p>

      chose que je ne sais pas est comment faire canexecute () code> incendie dans la sortie de ObjectName code> Propriété du code ci-dessus. P>

      Réponses de Re Ben et ABE: P>

      • canexecuTechangeed () code> est le gestionnaire d'événements et le compilateur se plaint: p>

        L'événement 'System.Windows.input.icommand.CanexecuTecharged' ne peut apparaître que sur le côté gauche de + = ou - = p> blockQuote> li>

      • Il n'y a que deux autres membres de iCommand code>: exécuté () code> et canexecute () code> p> l > ul>

        Avez-vous un exemple qui montre comment puis-je faire appel de commande canexecute () code>. p>

        J'ai trouvé la classe d'assistance de commandement dans Délégationecommand. CS code> et je vais y examiner, il y a peut-être un mécanisme qui pourrait aider. P>

        Quoi qu'il en soit, idée que pour activer la commande basée sur l'entrée de l'utilisateur, il faut une commande "nudge" L'objet dans le code d'installation de propriétés a l'air maladroite. Il introduira les dépendances et l'un des gros points de MVVM les réduira. P>

        edit 2: strong> p>

        J'ai essayé d'activer canexecute code > En appelant addObjectCommand.raisecanexecuTecharged () code> à ObjectName code> Settre de propriété du code ci-dessus. Cela n'aide pas non plus. canexecute () code> est tiré quelques fois lorsque le formulaire est initialisé, mais après cela ne sera jamais exécuté à nouveau. Ceci est le code: p> xxx pré>

        edit 3: solution forte> p>

        comme Yanko Yankov et Jerkimball a écrit, le problème est la ressource statique. Lorsque j'ai changé la liaison des boutons comme Yanko suggéré: p> xxx pré>

        Les choses ont commencé à travailler immédiatement. Je n'ai même pas besoin raisecanexecuTecharged () code>. Maintenant canexecute code> incendie automatiquement. P>

        Pourquoi ai-je utilisé une ressource statique en première place? Em>

        Le code d'origine était de WPF MVVM Toolkit manuel . Exemple dans ce manuel définit des commandes en tant que ressource statique, puis la lie à l'élément de menu. La différence est que, au lieu de la propriété de chaîne dans mon exemple, le manuel MVVM fonctionne avec Observablecollection code>. P>

        EDIT 4: Explication finale forte> p>

        Je l'ai enfin obtenu. Tout ce que je devais faire était de lire des commentaires dans CommandReference Code> Classe. Il dit: p> xxx pré>

        donc, CommandReference code> est utilisé pour keybinding code>, il ne doit pas être contraignant dans des éléments visuels. Dans le code ci-dessus, les références de commandes définies dans des ressources fonctionnent pour le clavier, que je n'ai pas sur ce contrôle de l'utilisateur.
        Bien entendu, un exemple de code fourni avec WPF MVVM Toolkit était correct, mais j'ai mal interprété et utilisé CommandReference code> dans la liaison des éléments visuels.
        Ce WPF MVVM est vraiment délicat parfois. P> p>


1 commentaires

En théorie, cela devrait fonctionner. Puisque vous mentionnez DélégationMommand, devrions-nous supposer que vous utilisez Prism / Cal, ou mettez-vous en œuvre ICommand vous-même? Certains code source seraient utiles à regarder. Par exemple, à quoi ressemble la liaison du bouton (en code). Comment méfiez-vous Délégatecommand, ou si vous le mettez en œuvre vous-même, à quoi ressemble cette mise en œuvre, etc.


6 Réponses :


1
votes

essayez d'augmenter canexecuTechanged lorsque votre propriété change. La liaison de la commande est vraiment distincte de la liaison de la propriété et les boutons liés aux commandes sont alertés à un changement de statut par l'événement CANEXecuTechanged .

Dans votre cas, vous pouvez déclencher un chèque lorsque vous effectuez le document sur la propriété liée qui l'évaluerait et définissez la commande interne canexecute drapeau, puis augmente < Code> CanexCuTecharged . Plus d'un "push" dans l'objet icommand qu'un "tirage".


1 commentaires

Veuillez vérifier la question à nouveau, j'ai ajouté du code et des commentaires concernant votre réponse



3
votes

Étant donné que vous utilisez la DélégationCommand, vous pouvez appeler sa méthode raisecanexecutangeté lorsque votre propriété de texte change. Je ne sais pas ce que vous essayez d'accomplir avec votre ressource de commandement, mais vous ne liez généralement que les commandes directement à la propriété de commande de l'élément de bouton: xxx

Ce serait la partie correspondante de votre Modèle de vue: xxx


1 commentaires

Veuillez vérifier la question à nouveau, j'ai ajouté du code et des commentaires concernant votre réponse



1
votes

faisant écho à Abe ici, mais le chemin "droit" à prendre ici utilise:

public void RaiseCanExecuteChanged();


1 commentaires

Jer, votre commentaire sur la réponse de Yanko avait raison. S'il vous plaît voir Edition3 pour expliquer.



4
votes

Les choses sont beaucoup plus claires maintenant avec les modifications, merci! Cela pourrait être une question stupide (je suis un peu fatigué d'une longue journée de travail), mais pourquoi ne pas vous attaquer directement au commandement, au lieu de passer une ressource statique?

<Button Command="{Binding AddObjectCommand}">Add</Button>


3 commentaires

C'est aussi mon premier chasseur, car une ressource statique ne sera pas réévaluée continuellement, même appeler le raisecanexecutéchangé ne va pas faire beaucoup.


Oui, on dirait qu'il lie le bouton d'une instance statique du modèle d'affichage, qui est un exemple différent de celui de la zone de texte est lié à, et probablement que l'ancien instance manque de connexion au monde extérieur pour commencer.


Tu avais raison. Le problème est avec la ressource statique. S'il vous plaît voir Edition3 pour expliquer.



1
votes

Je sais que c'est une ancienne question mais je pense personnellement qu'il est plus facile de lier la longueur de la Textbox la longueur à la propriété iSeNabled de bouton , par exemple: xxx


0 commentaires

0
votes

Si la liaison NomName ne fonctionne pas, utilisez:

p>

<Entry x:Name="Number1" Text="{Binding Number1Text}" Placeholder="Number 1" Keyboard="Numeric"></Entry>
<Entry x:Name="Number2" Text="{Binding Number2Text}" Placeholder="Number 2" Keyboard="Numeric"></Entry>

<Button VerticalOptions="Center" Text="Calculate" x:Name="btnCalculate" Command="{Binding CalculateCommand}">
<Button.Triggers>
  <DataTrigger TargetType="Button"
               Binding="{Binding Source={x:Reference Number1, Number2},
                                 Path=Text.Length}"
               Value="{x:Null}">
      <Setter Property="IsEnabled" Value="False" />
  </DataTrigger>
</Button.Triggers>


0 commentaires