7
votes

Modifier la couleur de fond pour la zone de texte WPF dans l'état modifié

J'ai une classe EmployeeViewModel avec 2 propriétés "Prénom" et "Nom". La classe a également un dictionnaire avec les changements des propriétés. (La classe implémente inotifyPropertychangned et idataerrrorinfo, tout va bien.

à mon avis, il y a une zone de texte: xxx

Comment puis-je modifier la couleur de fond de la zone de texte, si La valeur initiale a changé? J'ai pensé à créer un déclencheur qui définit la couleur d'arrière-plan mais que dois-je lier? Je ne veux pas créer de propriété supplémentaire pour chaque contrôle qui contient l'état Wheile que celui qui a été changé ou non.

thx


1 commentaires

Un besoin très courant dans WPF ... Il est toujours surpris que le cadre ne fournisse pas un événement simple pour cela, peut-être sur la classe contraignante


6 Réponses :


4
votes

6 commentaires

Et à quoi devrais-je maintenant lier la couleur de fond? Une méthode, une entrée de dictionnaire, un champ, une propriété? Ou je manque totalement quelque chose. Je pense que la seule façon de travailler peut-elle être pratique serait un dictionnaire, mais cela n'est pas pris en charge par InotitPropertyChanged?


Comme je l'ai dit, liez le fond de la propriété de texte.


J'ai fait un exemple pour vous, pour montrer comment la liaison pourrait être accomplie.


Merci pour l'exemple, je comprends maintenant le concept. Le problème restant que j'ai est de savoir comment gérer la communication entre l'évaluateur et le modèle de vision. Une fois que tout le texte par défaut n'est pas statique, mais plutôt une valeur d'une logique de domaine avant de modifier. Accéder au modèle de vue à l'intérieur de l'évaluateur semble un peu sale pour moi.


AHA, vous avez frappé l'un des problèmes majeurs à l'aide de M-V-VM et d'objets de valeur dans des liaisons. Une solution serait de transmettre la chaîne par défaut en tant que converterparameter. Cela contournerait de devoir vérifier une propriété sur le point de vue, mais l'inconvénient est que vous devez définir ce converterparameter. Honnêtement, cependant, il n'y a pas de balle d'argent pour le problème de conception que vous mentionnez. C'est quelque chose qui peut être abordé de nombreuses manières différentes.


J'avais compris depuis que j'ai posté ceci, fond = "{nom = backcolor}" et dans la classe de reliure rendit la propriété Backcolor Vérifiez la valeur, mais l'apparence des boutons est maintenant plate. J'espérais que cette méthode serait meilleure.



1
votes

Vous pouvez ajouter à vos propriétés de ViewModel Boolean, telles que Isfirstnamemodifié et ISlastnamemodifié et utilisez un déclencheur pour modifier l'arrière-plan si la zone de texte en fonction de ces propriétés. Ou vous pouvez lier l'arrière-plan sur ces propriétés, avec un convertisseur qui renvoie une brosse d'un ...


1 commentaires

Cette solution est moins optimale car elle implique d'ajouter deux fois plus de propriétés (vous devrez garder une trace des propriétés islamématiques ainsi qu'une valeur originale afin de pouvoir déterminer si le nom a été modifié). Ajout de déclencheurs est également plus de travail que nécessaire. Je voudrais lier directement au texte et utiliser un convertisseur.



3
votes

Si vous utilisez le paradigme MVVM, vous devez prendre en compte les images de vue comme ayant le rôle d'adaptateurs entre le modèle et la vue.

On ne s'attend pas à ce que la vue est complètement agnostique de l'existence d'une interface utilisateur À tous égards, mais d'être agnostique de tout spécifique em> ui. p>

Donc, le point de vue peut (et devrait) avoir la fonctionnalité de autant de convertisseurs que possible. L'exemple pratique ici serait là: p>

une interface utilisateur doit savoir si un texte est égal à une chaîne par défaut? Em> p>

si la réponse est oui em>, il suffit de mettre en place une propriété isdefaultstring code> sur une vue de vue. p> xxx pré>

puis lier la zone de texte / Code> Comme ceci: p>

<TextBox x:Name="textBox" Background="White" Text="{Binding Path=TheText, UpdateSourceTrigger=LostFocus}">
    <TextBox.Resources>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsTextDefault}" Value="False">
                    <Setter Property="TextBox.Background" Value="Red"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Resources>
</TextBox>


0 commentaires

0
votes

Une variation de la dernière réponse pourrait être de toujours être dans l'état modifié, sauf si la valeur est la valeur par défaut.

xxx


1 commentaires

Tout cela pour passer à la propriété de fond? JavaScript - this.style.backgroundColor = "jaune"; Il doit y avoir un moyen plus facile.



1
votes

Un moyen différent de manière différente de ne pas mettre en œuvre inotifyPropertychanged et de descendre de dépendanceObject ou uielement

Ils mettent en œuvre la liaison à l'aide de la dépendanceProperty Vous pouvez utiliser un événement d'utilisation d'un seul gestionnaire d'événements et utilisateur E.Property pour trouver la zone de rigueur

Je suis à peu près sûr que la vérification E.Newvalue! = E.OldValue est redondante, car la liaison n'aurait pas été modifiée. Je peux aussi croire qu'il peut y avoir un moyen de mettre en œuvre la liaison afin que la dépendecyobject est la zone de texte et non votre objet ...

Modifier si vous héritez déjà de n'importe quelle classe WPF (comme contrôle ou userControl), vous êtes probablement OK et vous n'avez pas besoin de changer d'uielement comme la plupart des hérités du WPF de cette classe

alors vous pouvez avoir: xxx


0 commentaires

12
votes

Utilisez simplement un multibelling avec la même propriété deux fois mais avez le mode = OneTime sur l'une des fixations. Comme ceci: xxx

et dans xaml: xxx

aucune propriété supplémentaire ou logique requise et que vous pourriez probablement tout emballage dans votre propre Extension de balise. Espère que cela aide.


0 commentaires