Liaison de données WPF et IValueConverter
Pourquoi est-il que lorsque j'utilise un convertisseur dans mon expression de liaison dans WPF, la valeur n'est pas mise à jour lorsque les données sont mises à jour.
J'ai une Personne simple modèle de données:
class Person : INotifyPropertyChanged
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Mon expression de liaison ressemble à ceci:
<TextBlock Text="{Binding Converter={StaticResource personNameConverter}" />
Mon convertisseur ressemble à ceci:
class PersonNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Person p = value as Person;
return p.FirstName + " " + p.LastName;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Si je la liaison de données sans convertisseur il fonctionne très bien:
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
Ce qui me manque?
EDIT:
Juste pour clarifier un peu les choses, Joel et Alan sont corrects concernant l'interface INotifyPropertyChanged qui doit être mis en œuvre. En réalité, je dois effectivement mettre en œuvre mais cela ne fonctionne toujours pas.
Je ne peux pas utiliser de multiples éléments TextBlock parce que je suis en train de lier le Titre de la Fenêtre pour le nom complet et le Titre de la Fenêtre ne prenez pas un modèle.
Enfin, c'est une option à ajouter un composé de propriété "FullName" et de se lier à elle, mais je me demande encore aujourd'hui pourquoi la mise à jour ne se produit pas lorsque la liaison utilise un convertisseur. Même quand je mets un point d'arrêt dans le convertisseur de code, le débogueur n'est pas là quand une mise à jour est faite pour les données sous-jacentes 🙁
Grâce,
Uri
source d'informationauteur urini
Vous devez vous connecter pour publier un commentaire.
(voir les modifications ci-dessous; plus tard: #2)
Ce n'est pas la mise à jour parce que votre
Person
objet n'est pas capable de notifier tout ce que la valeur deFirstName
ouLastName
a changé. Voir cette Question.Et voici comment la mettre en œuvre
INotifyPropertyChanged
. (Mis à jour, voir Edit 2)Edit 1
En fait, depuis que vous êtes après le prénom et le nom de la mise à jour, et
Path=FirstName
et tel fonctionne très bien, je ne pense pas que vous aurez besoin du convertisseur. PlusieursTextBlocks
sont tout aussi valide, et peut réellement fonctionner mieux quand vous êtes à la localisation d'un droit-à-gauche de la langue.Edit 2
J'ai pensé à elle. Il n'est pas informé que les propriétés ont mis à jour parce que c'est la liaison de l'objet lui-même, pas un de ces propriétés. Même quand j'ai fait
Person
unDependencyObject
et faitFirstName
etLastName
DependencyProperties
il ne serait pas mise à jour.Vous sera utiliser un
FullName
bien, et je l'ai mise à jour du code de laPerson
classe ci-dessus pour refléter cela. Ensuite, vous pouvez lier leTitle
. (Remarque: j'ai mis lePerson
objet que l'Window
'sDataContext
.)Si vous modifiez les noms dans une
TextBox
et souhaitez que le nom a été changé immédiatement répercutées au lieu de quand laTextBox
perd le focus, vous pouvez le faire:Je sais que vous ne voulez pas utiliser un
FullName
bien, mais quelque chose qui leur permettrait de réaliser ce que vous voulez serait probablement un peu de Rube Goldberg appareil. Comme la mise en placeINotifyPropertyChanged
et unPerson
bien sur laWindow
classe elle-même, ayant laWindow
écouter sur lePropertyChanged
événement afin de le feu laWindow
'sPropertyChanged
de l'événement, et à l'aide d'un relatif de liaison comme suit. Il faudrait aussi définir laPerson
bien avantInitializeComponent()
ou d'incendiePropertyChanged
après le réglage de laPerson
de la propriété de sorte qu'il se montre, bien sûr. (Sinon, il seranull
pendantInitializeComponent()
et a besoin de savoir quand il est unPerson
.)Vous pouvez également utiliser un MultiBinding.. se Lient à la Personne objet, FirstName et LastName. De cette façon, la valeur est mise à jour dès que le Prénom ou Nom de jette, la propriété a changé de l'événement.
Ou si vous utilisez uniquement le FirstName et LastName, bande de la Personne objet de la liaison à quelque chose comme ceci:
Et la MultiValueConverter ressemble à ceci:
Mais bien sûr, la réponse sélectionnée fonctionne aussi bien, mais un MultiBinding fonctionne plus...
Pour que la liaison soit mis à jour, votre personne de la classe doit implémenter INotifyPropertyChanged de laisser la liaison savoir que les propriétés de l'objet ont été udpated. Vous pouvez également vous sauver de l'extra convertisseur en fournissant une propriété fullName.
Votre Liaison va maintenant ressembler à ceci:
Je n'ai pas vérifier, mais vous pouvez aussi essayer le suivant