views:

882

answers:

3

Hello, please take a look at the following line

<TextBox Text="{Binding Price}"/>

This Price property from above is a Decimal? (Nullable decimal).

I want that if user deletes the content of the textbox (i.e. enters empty string, it should automatcally update source with null (Nothing in VB).

Any ideas on how I can do it 'Xamly'?

+2  A: 

You can try using a ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

Of the back of my head here, something like:

public class DoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return (double)value;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
    var doubleValue = Convert.ToDouble(value);

    return (doubleValue == 0 ? null : doubleValue);
    }
}

(Might need some tweaking though)

TimothyP
I would prefer a Xamly way, but I can't think of anything
Shimmy
+2  A: 

This value converter should do the trick :

public class StringToNullableDecimalConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
        CultureInfo culture)
    {
        decimal? d = (decimal?)value;
        if (d.HasValue)
            return d.ToString(culture);
        else
            return String.Empty();
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        string s = (string)value;
        if (String.IsNullOrEmpty(s))
            return null;
        else
            return (decimal?)decimal.Parse(s, culture);
    }
}

Declare an instance of this converter in the ressources :

<Window.Resources>
    <local:StringToNullableDecimalConverter x:Key="nullDecimalConv"/>
</Window.Resources>

And use it in your binding :

<TextBox Text="{Binding Price, Converter={StaticResource nullDecimalConv}}"/>

Note that TargetNullValue is not appropriate here : it is used to define which value should be used when the source of the binding is null. Here Price is not the source, it's a property of the source...

Thomas Levesque
Any xamly ideas?
Shimmy
A converter is the proper way to do this, and you can't define these converters in XAML. Converters allow you to change the default "object to object" conversion behavior in data-binding, which is what you're wanting to do.
Will Eddins
The problem in my case is that I already use a convereter here that does another thing.I posted an answer, please take a look.
Shimmy
+6  A: 

I am using .NET 3.5 SP1 so it's very simple:

<TextBox Text="{Binding Price, TargetNullValue={x:Static sys:String.Empty}}"/>

'sys' is the imported xml namespace for System in mscorlib:

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

Hope that helped.

Shimmy
see my updated answer
Thomas Levesque
Actually TargetNullValue works just fine. What it does is set an equivalence between the given value and null. So in this case when the bound value is null it will display an empty string and when the target's value is the empty string it will set the bound value to null.
Bryan Anderson