views:

9

answers:

1

I'm running into an issue with a formatting converter and data validation. I have the following textbox XAML declaration

<TextBox FontFamily="Segoe" FontSize="16" FontWeight="Medium"
    TabIndex="{Binding TabBinding}"  Foreground="Black"
    Opacity="0.9" IsTabStop="True" Uid="{Binding PriceID}"
    Text="{Binding NewPrice,Converter={StaticResource FormattingConverter},
    ConverterParameter=' \{0:C\}', Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
    Background="#FFE6DED3" BorderBrush="#FFE6DED3"
    DataContext="{Binding StringFormat=\{0:c\}, NotifyOnValidationError=True}"
    Padding="0" KeyDown="TextBox_KeyDown" AcceptsReturn="False">
</TextBox>

The issue I'm up against is a data validation issue. When a user enters an invalid price (Ex: a value of "abc" or "0.0.4"), the textbox attempts to perform the conversion in the "FormattingConverter" method. (ConvertBack method pasted below) This causes an exception and the program errors out. Is there a way to delay the FormattingConverter call or bypass it if the data in the textbox is not valid?

public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
{
    var objTypeConverter = System.ComponentModel.TypeDescriptor.GetConverter(targetType);
    object objReturnValue = null;

    if (objTypeConverter.CanConvertFrom(value.GetType())) {
        objReturnValue = objTypeConverter.ConvertFrom(value.ToString().Replace("$", ""));
    }

    return objReturnValue;
}

Thank you,

+1  A: 

A converter's ConvertBack always runs to convert the data to a value suitable for the target object. It is the responsibility of the converter to handle exceptions (and in the case of exception, return the original value so the binding framework will also realize it's an invalid value).

public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)  
{ 
    var objTypeConverter = System.ComponentModel.TypeDescriptor.GetConverter(targetType); 
    // Default return value is the original value - if conversion fails, return
    // this value so the binding framework will see an invalid value (and not 
    // just null).
    object objReturnValue = value; 

    if (objTypeConverter.CanConvertFrom(value.GetType())) { 
        try {
            objReturnValue = objTypeConverter.ConvertFrom(value.ToString().Replace("$", "")); 
        }
        catch( FormatException ) { }
        // Catch all of your possible exceptions and ignore them by returning the original value
    } 

    return objReturnValue; 
} 

You can also return DependencyProperty.UnsetValue, however in practice I prefer to see the actual error message returned in validation from an invalid value than to simply return an unset value.

Adam Sills
@Adam ahhh gotcha ! so I can use the "IsValid" method of the type converter to see if I can convert the value in the first place and if not just throw back whatever was entered and let the textbox flag it as an error.
Scott Vercuski
IME, that's the easiest way to deal with it. The docs say to use UnsetValue, but I've never liked doing that in practice. http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.convert.aspx
Adam Sills
@Adam just implemented it ... worked like a charm !!! thanks !!!
Scott Vercuski