2

I have a TextBox in XAML which I'm trying to databind to a nullable int. This is the code for my textbox and linked converter:

<TextBox x:Name="textArea" InputScope="Number" Text="{Binding Area, Mode=TwoWay, Converter={StaticResource NullableValueConverter}}" />

public class NullableValueConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        if (String.IsNullOrEmpty(value.ToString()))
        {
            return null;
        }

        return value;
    }
}

When every I enter a number in this textbox the databind doesn't seem to work and the datasource is always left as null. How can I get round this?

I'm using XAML & C# to design a windows store application.

Thanks in advance.

Sun
  • 4,458
  • 14
  • 66
  • 108

3 Answers3

6

I agree with Sacha's answer, but if you need a NullableValueConverter an improvement would be

public class NullableValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
                          CultureInfo culture)
    {
        return value == null ? string.Empty : value.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, 
                              CultureInfo culture)
    {
        string s = value as string;

        int result;
        if (!string.IsNullOrWhiteSpace(s) && int.TryParse(s, out result))
        {
            return result;
        }

        return null;
    }
}

Note that this was tested using WPF so the method signatures may be different from WinRT.

Phil
  • 42,255
  • 9
  • 100
  • 100
  • Hi Phil, thanks for the reply. Please see my comment on Sascha's post – Sun Mar 14 '13 at 10:45
  • 1
    No problem. Thinking about it you could remove the !string.IsNullOrWhiteSpace because int.TryParse will return false for null or whitespace. – Phil Mar 15 '13 at 08:44
2

In your binding handle TargetNullValue. Somewhat like:

You'll need to add mscorlib:

 xmlns:sys="clr-namespace:System;assembly=mscorlib"

and update your binding like so:

 Source="{Binding Area,
          TargetNullValue={x:Static sys:String.Empty},
          Converter={StaticResource NullableValueConverter}}"

Actually you wont need the NullableValueConverter if you check for a null value in your XAML. This depends of course what else your converter is possibly supposed to handle.

Alternatively you could implement IDataErrorInfo. That is a bit more complex tho.

Sascha Hennig
  • 2,556
  • 1
  • 19
  • 22
  • Thanks for the reply. When I add the reference it complains with the following error: Undefined CLR namespace. The 'clr-namespace' URI refers to a namespace 'System' that could not be found. I'm using a window surface RT device for this application. Not sure it that changes anything? – Sun Mar 14 '13 at 10:41
  • In some code behind file right click on the `String` type keyword and choose "Go to definition". This should open the metadata for the class the type is defined in. On the top you'll see the assembly name and of course the namespace. Replace those in your binding if they differ from the mentioned values. – Sascha Hennig Mar 14 '13 at 12:30
  • OK, I've added the following reference now: xmlns:sys="clr-namespace:System;assembly=System.Runtime" and the compiler accepts this. I now receive the following error: The member "TargetNullValue" is not recognized or is not accessible. Do I need another reference to get TargetNullValue? – Sun Mar 14 '13 at 14:34
  • in WPF `TargetNullValue` is defined in PresentationFramework.dll as Member of `System.Windows.Data.BindingBase`. Well that wont help you much I guess. Do a search for `TargetNullValue` in the ObjectCatalog and see if it is defined in an assembly which you dont yet reference in your project. I was not aware that the WinRT differs that much from WPF. Anyhow - if that ObjectCatalog search is not successful I would recommend to implement Phils solution as it is valid and apparently a lot less of a hassle. – Sascha Hennig Mar 14 '13 at 14:53
2

There's no TargetNullValue property on Binding class for Windows Store apps.

Phil's approach is valid and it works fine, just make sure you're using the correct method signatures as he suggested (and as you already did in your own version of NullableValueConverter):

public class NullableValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value == null ? string.Empty : value.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        string s = value as string;

        int result;
        if (!string.IsNullOrWhiteSpace(s) && int.TryParse(s, out result))
        {
            return result;
        }

        return null;
    }
}
Damir Arh
  • 17,637
  • 2
  • 45
  • 83