Change la Couleur de Fond pour WPF zone de texte dans changé à l'état d'
J'ai une classe EmployeeViewModel avec 2 propriétés "Prénom" et "Nom". La classe a aussi un dictionnaire avec les changements de propriétés. (La classe implémente INotifyPropertyChanged et IDataErrorInfo, tout va bien.
À mon avis, il y a une zone de texte:
<TextBox x:Name="firstNameTextBox" Text="{Binding Path=FirstName}" />
Comment puis-je changer la couleur de fond de la zone de texte, si la valeur d'origine changé? J'ai pensé à créer un déclencheur qui définit la couleur d'arrière-plan, mais à quoi dois-je lier?
Je ne veux pas créé une propriété supplémentaire pour chaque contrôle qui maintient l'état que l'on a été changé ou pas.
Thx
- un très commune dans WPF... c'est toujours un peu surpris de m'que le cadre ne fournit pas un simple événement pour cela, peut-être sur la liaison de la classe
Vous devez vous connecter pour publier un commentaire.
Il suffit d'utiliser un MultiBinding avec la même propriété deux fois, mais ont Mode=OneTime sur l'une des liaisons. Comme ceci:
Et dans le code xaml:
Pas de propriétés supplémentaires ou de logique, nécessaire et vous pourriez probablement envelopper le tout dans votre propre extension de balisage. Espérons que cela aide.
Vous aurez besoin d'utiliser un convertisseur de valeurs (conversion d'entrée de chaîne de couleur de sortie) et la solution la plus simple consiste en l'ajout d'au moins une propriété à votre EmployeeViewModel. Vous avez besoin de faire une sorte de par Défaut ou OriginalValue des biens, et de les comparer à l'encontre de cela. Sinon, comment allez-vous savoir ce qu'est la "valeur d'origine" a été? On ne peut pas dire si la valeur a changé, sauf si il ya quelque chose de dépositaire de l'original de la valeur à comparer.
Donc, lier à la propriété de texte et de comparer la chaîne d'entrée à la valeur d'origine sur le modèle de vue. Si elle a changé, de retour en surbrillance votre couleur d'arrière-plan. Si elle correspond, de retour à la normale de la couleur d'arrière-plan. Vous aurez besoin d'utiliser un multi-obligatoire si vous voulez comparer les Prénom et LastName ensemble à partir d'une seule zone de texte.
J'ai construit un exemple qui montre comment cela pourrait fonctionner:
Et voici le code-behind de la Fenêtre:
Enfin, voici le convertisseur vous utilisez:
Et même si j'ai enveloppé d'une bordure autour de la zone de texte (parce que je pense que c'est un peu mieux), l'arrière-plan de liaison peut être réalisée exactement de la même manière:
Background="{Name=BackColor}"
et dans la classe binding fait la propriété BackColor vérifier la valeur, mais l'aspect des boutons sont maintenant à plat. J'espérais que cette méthode serait mieux.Si vous utilisez le MVVM paradigme, vous devriez envisager de le Viewmodel comme ayant le rôle d'adaptateur entre le Modèle et la Vue.
Il n'est pas prévu de le ViewModel pour être complètement agnostique de l'existence d'une INTERFACE utilisateur dans tous les sens, mais pour être agnostique de toute spécifiques de l'INTERFACE utilisateur.
Donc, le ViewModel peut (et doit) avoir la fonctionnalité de Convertisseurs de nombreux que possible. L'exemple pratique ici serait celui-ci:
Serait une INTERFACE utilisateur nécessitent de savoir si un texte est égal à une chaîne par défaut?
Si la réponse est oui, c'est une raison suffisante pour mettre en œuvre un
IsDefaultString
propriété sur un ViewModel.Puis de lier la
TextBox
comme ceci:Que cela se propage texte vers le ViewModel sur
TextBox
perdre le focus, ce qui entraîne un nouveau calcul de laIsTextDefault
. Si vous avez besoin pour ce faire d'un grand nombre de fois, ou pour de nombreuses propriétés, vous pouvez même cuire jusqu'à quelques de la classe de base commeDefaultManagerViewModel
.Vous pouvez ajouter à votre ViewModel propriétés booléennes comme
IsFirstNameModified
etIsLastNameModified
, et utiliser un déclencheur pour changer le fond si la zone de texte en fonction de ces propriétés. Ou, vous pouvez lier leBackground
à ces propriétés, avec un convertisseur qui renvoie unBrush
à partir d'un bool...Complète diferent façon serait de ne pas implémenter INotifyPropertyChanged et, au lieu de descendre de DependencyObject ou UIElement
Ils mettent en œuvre la liaison à l'aide de DependencyProperty
Vous pouvez utiliser un seul gestionnaire d'événement et de l'utilisateur e.Propriété à trouver la droite de zone de texte
Je suis sûr que l'e.NewValue != e.OldValue vérification est inutile parce que la liaison ne devrait pas avoir changé. J'ai aussi beleive il y a peut être une façon de mettre en œuvre la liaison pour le dependecyObject est la zone de texte et pas votre objet...
Modifier si vous avez déjà hériter de toute WPF classe (comme le contrôle ou le contrôle usercontrol) vous êtes probablement ok et vous n'avez pas besoin de changer de UIElement comme la plupart de WPF héritent de cette classe
Alors vous pouvez avoir:
Une variation de la dernière réponse pourrait être de alwais être dans la nouvelle état, à moins que la valeur est la valeur par défaut.