views:

503

answers:

2

OK, working on WPF(using MVVM) and came across a question, want some input. I have a simple class

like below(assume I have IDataErrorInfo implemented):

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

I then try to bind to it in xaml:

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

when a user then clears out the text, a databinding error occurs because it cant convert string.empty to int. Well, Fee is a required field, but because the databinding won't convert back I can't provide error information because my class isn't updated. So am I required to then do the following?

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

This can be done using a 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;
        }
    }
}

You reference it in the XAML thus:

<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>
Dabblernl
+1  A: 

You can also take advantage of the fact you're doing MVVM and change the type of the Fee property to string. After all, your VM should provide a model that supports the view, and the view allows users to enter a string. Then you can provide a separate property that exposes the parsed fee as an int. That way your conversion logic is right there in the Fee property, making it easier to reuse, debug, and maintain.

HTH, Kent

Kent Boogaart
I am not sure if I agree with you. The Fee seems to be a property you will make calculations with, so should be numeric. All numeric fields will be enterend through textboxes accepting strings. The way you propose it you would have to implement all properties that represent numbers with both a string and a numeric variant. Using a converter you have to write the conversion code just once.
Dabblernl
There's no reason you have to write conversion code more than once - just factor it out as necessary. Usually, however, it's just a simple call to a TryParse method so there's no pain there. Also, putting the code in the VM means less can go wrong in the view, where you designers will be playing.
Kent Boogaart