2009-06-08 12 views
4

OK, en travaillant sur WPF (en utilisant MVVM) et rencontré une question, vous voulez une entrée. J'ai une classe simpleNotification d'erreur de liaison de liaison de données WPF

comme ci-dessous (en supposant que je IDataErrorInfo mis en œuvre):

public class SimpleClassViewModel 
{ 
    DataModel Model {get;set;} 
    public int Fee {get { return Model.Fee;} set { Model.Fee = value;}} 
} 

J'essaie alors de se lier à elle en XAML:

<TextBox Text={Binding Fee, ValidatesOnDataErrors=true}/> 

lorsqu'un utilisateur efface alors la text, une erreur de liaison de données se produit car il ne peut pas convertir string.empty en int. Eh bien, Fee est un champ obligatoire, mais comme la liaison de données ne sera pas reconvertie, je ne peux pas fournir d'informations d'erreur car ma classe n'est pas mise à jour. Alors suis-je obligé de faire ce qui suit?

public class SimpleClassViewModel 
{ 
    DataModel Model {get;set;} 
    int? _Fee; 
    public int? Fee 
    { 
    get { return _Fee;} 
    set { _Fee = value;if (value.HasValue) { Model.Fee = value;} 
    } 
} 

Répondre

5

Cela peut être fait en utilisant un ValueConverter:

using System.Windows.Data; 

namespace MyNameSpace 
{ 
    class IntToStringConverter:IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      return ((int) value).ToString(); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      int result; 
      var succes = int.TryParse((string) value,out result); 
      return succes ? result : 0; 
     } 
    } 
} 

Vous désignez dans le XAML ainsi:

<Window xmlns:local="clr-namespace:MyNameSpace"> 
    <Window.Resources> 
     <local:IntToStringConverter x:Key="IntConverter"/> 
    </Window.Resources> 
    <TextBox Text={Binding Fee, ValidatesOnDataErrors=true, 
      Converter={StaticResource IntConverter}}/> 
</Window> 
2

Vous pouvez également profiter du fait que vous faites MVVM et remplacez le type de la propriété Fee par string. Après tout, votre machine virtuelle doit fournir un modèle qui prend en charge la vue, et la vue permet aux utilisateurs d'entrer un string. Vous pouvez ensuite fournir une propriété distincte qui expose les frais analysés en tant que int. De cette façon, votre logique de conversion est présente dans la propriété Fee, ce qui facilite la réutilisation, le débogage et la maintenance.

+0

Je ne suis pas sûr si je suis d'accord avec vous. La taxe semble être une propriété avec laquelle vous ferez des calculs, elle devrait donc être numérique. Tous les champs numériques seront enterend à travers des boîtes de texte acceptant des chaînes. La façon dont vous le proposez implémenterait toutes les propriétés qui représentent des nombres avec une chaîne et une variante numérique. En utilisant un convertisseur, vous devez écrire le code de conversion une seule fois. – Dabblernl

+1

Il n'y a aucune raison de devoir écrire le code de conversion plus d'une fois - il suffit de le factoriser si nécessaire. Habituellement, cependant, c'est juste un simple appel à une méthode TryParse, donc il n'y a pas de douleur là-bas. De plus, mettre le code dans la VM signifie que moins de choses peuvent mal se passer dans la vue, où les concepteurs vont jouer. –