Changed behaviour from .Net 3.5 to .Net 4.0 of WPF TextBox formatting when PropertyChanged is used as UpdateSourceTrigger - by Thies Schrader

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 588343 Comments
Status Closed Workarounds
Type Bug Repros 9
Opened 8/23/2010 5:37:15 AM
Access Restriction Public


Using the .Net 4 Framework and editing a WPF textbox bound to a nullable decimal, where formatting is specified along with the PropertyChanged UpdateSourceTrigger, the number is formatted while being edited, causing incorrect entering of numbers.

Old behavoiur was that formatting was not done to the number until the field was exited, whereas the underlying property was updated as keys where pressed.

Work arounds (not optimal): Do not use PropertyChanged - UpdateSourceTrigger but LostFocus instead.
Sign in to post a comment.
Posted by Maximilian Haru Raditya on 3/26/2012 at 8:59 AM
@candritzky: That's interesting, I become curious what's meant by "fixed" here. I haven't tried with WPF 4.5 BETA yet, maybe later.
Posted by candritzky on 3/26/2012 at 5:22 AM
I, too, experience the same problem, but in a much simpler context. Simply bind a TextBox.Text property to a property of type TimeSpan with UpdateSourceTrigger=PropertyChanged. You will see that it is hardly possible to enter the desired TimeSpan value.

As you at MS marked this issue as "Fixed" I tried to today with VS11 Beta and .NET 4.5 Beta, but the issue is still present.
Posted by Thies Schrader on 7/18/2011 at 12:38 AM
Thank you for the reply.

The main issues we have are;
- updating other GUI elements based of the values entered. That is, if you enter a number into one field, 5 other fields should be displayed for details. If we use LostFocus, we need to wait until the user exits the field to get an event to update the GUI, which messes up the tab-order in our forms.
- making sure there are not unsaved changes when a form is closed. Given a textbox has focus, and the user updates the value in the text box - the user then closes the form using the red 'X'. When this happens, the underling property is not updated, and the users changes are not caught (and therefore not saved)

In our case, we see this problem most often with text box fields, bound to a decimal number - where we have formatting set to N2. While the user enters a number, the cursor input position changes, and the number entered is different than the user's intent.

Maybe given the decimal value of the formatted version of the input string is the same as the decimal value of the non-formatted value, the formatting of the text box is not updated, e.g.:

if(DecimalValue(Formatted(textstring)) == DecimalValue(textstring))
     do not update textbox

textstring = "123456,5"
Formatted(textstring) == "123 456,50"     (based on N2 and European style locale)
DecimalValue(123456,5) == 123456,5

This would allow the user to enter the text as they see fit, and not see the text box being updated with characters they did not enter - causing repositioning and incorrect entering of numbers.
Posted by Microsoft on 1/12/2011 at 10:27 AM
The workaround you've already mentioned - use LostFocus instead of PropertyChanged - is the best you can do in 4.0. I assume by "not optimal" you mean that you sacrifice some behavior by doing this, chiefly the ability to show validation feedback after every keystroke.

In 3.5, the binding would write a new value back to the source after each keystroke, without changing the TextBox text. But that text might not represent the source's value accurately, perhaps because it doesn't include formatting and conversion, or because the source changed the value (in the property-setter) to something else. This led to frequent and vehement complaints - people wanted the TextBox to show the source's value, exactly as a TextBlock would if bound to the same property with the same converters and formatting. The UI should display what's actually in the data, not what the end-user typed.

To fix this class of bugs in 4.0, the binding now applies formatting and conversion to the source's new value after every update. (LostFocus bindings already did this in 3.5.) The TextBox now shows what's in the data, but that can make the user's typing more complex.

We plan to improve this scenario in the next release in at least two ways:
1. When the TextBox text is replaced with a revised string, the insertion point (cursor) that worked for the old string may no longer be correct for the new string. The heuristic that guesses where to put the cursor can be improved.
2. Bindings will expose a way to do LostFocus (or Explicit) updates with partial validation after each keystroke. The formatting/conversion only gets applied when focus changes, but the user gets validation feedback after every keystroke.

- Sam (WPF team)
Posted by Helen [MSFT] on 8/23/2010 at 9:19 PM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Posted by Maximilian Haru Raditya on 8/23/2010 at 5:16 PM
This bug also appears to happen when specifying a converter and setting UpdateSourceTrigger to PropertyChanged in a binding as well. For example:

<TextBox Text="{Binding Price, Converter={StaticResource PriceConverter}, UpdateSourceTrigger=PropertyChanged}" />

    [ValueConversion(typeof(decimal), typeof(string))]
    public class PriceAndStringConverter : IValueConverter
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            var returnValue = 0.0M;
            if (value is decimal)
                returnValue = (decimal) value;

            var convertedReturnValue = returnValue.ToString("C2", culture);
            return convertedReturnValue;

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            if (value == null)
                return Binding.DoNothing;

            decimal returnValue;
            if (!decimal.TryParse(value.ToString(), NumberStyles.Currency, culture, out returnValue))
                returnValue = 0.0M;

            return returnValue;
Posted by Microsoft on 8/23/2010 at 5:08 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(