2009-09-03 10 views
1

J'ai une classe, appelée DateField, qui a une propriété de chaîne Value. Si vous définissez cette propriété sur une chaîne qui peut être analysée en une date valide, le poseur de propriété met Value à la date correctement mis en forme, par exemple:Liaison bidirectionnelle WPF: comment mettre à jour un TextBox avec une version formatée de la valeur qu'il vient de définir?

private string _Value; 
    public string Value 
    { 
     get 
     { 
      return _Value; 
     } 
     set 
     { 
      if (value == _Value) 
      { 
       return; 
      } 
      object result; 
      if (TryParse(value, out result)) 
      { 
       _Value = Format(result); 
      } 
      else 
      { 
       _Value = value; 
      } 
      OnPropertyChanged("Value"); 
     } 
    } 

Je crée une zone de texte qui est lié à ce domaine:

<DataTemplate DataType="{x:Type m:DateField}"> 
     <TextBox           
       IsTabStop="True" 
       Text="{Binding Value, Mode=TwoWay, ValidatesOnDataErrors=True}"> 
     </TextBox> 
    </DataTemplate> 

Lorsque j'entre, par exemple, "010109" dans ce champ et une tabulation, le Binding définit correctement la propriété Value sur cette chaîne. La propriété setter s'exécute, _Value est correctement défini sur "01/01/2009" (l'implémentation TryParse dans cette classe est un peu plus catholique dans ce qu'elle accepte que DateTime.TryParse is) et l'événement PropertyChanged est déclenché. Je sais que ce dernier est en train de se passer parce qu'un autre objet abonné à la liste est mis à jour. Mais le TextBox ne le fait pas. Pourquoi pas? J'ai mis Value, j'ai soulevé PropertyChanged; que dois-je faire de plus?

Répondre

2

Je pense que vous devriez utiliser un converter et mettre en œuvre à la fois la Convert et les méthodes ConvertBack

+0

Terminé; voir ma réponse pour plus de détails. –

1

Je pense avoir ce travail correctement, mais je ne suis pas entièrement satisfait de la façon dont je l'ai fait.

Le modèle typique pour l'utilisation d'un ValueConverter est que le ConvertBack doit renvoyer la valeur convertie si l'analyse a réussi, et DependencyProperty.UnsetValue en cas d'échec. Je ne peux pas faire ça. Si je fais cela, la propriété Value liée n'est pas définie. La valeur n'est donc pas validée et aucune erreur de validation n'apparaît dans l'interface utilisateur. Ce que j'ai fait à la place est implémenté une classe DateValueConverter dont la méthode ConvertBack renvoie la DateTime parsée, ou la chaîne qu'elle a essayé de convertir sans succès. La propriété Value dans ma DateTimeField classe (en fait, dans la classe Field il est dérivé) ressemble à ceci:

public object Value 
{ 
    get 
    { 
     return _Value; 
    } 
    set 
    { 
     if (value == _Value) 
     { 
      return; 
     } 

     if (!Validate(value)) 
     { 
      return; 
     } 

     _Value = value; 
     OnPropertyChanged("Value"); 
    } 
} 

La méthode Validate ressemble fondamentalement juste au type de la valeur transmise dans: si c'est un DateTime, alors c'est valide; si c'est une chaîne, ce n'est pas le cas.

Je ne suis pas satisfait de cela parce qu'il semble que ValueConverter ne devrait pas convertir une valeur en deux types différents. On se sent comme un hack. Mais peut-être que c'est bon. Je dois y réfléchir un peu plus.