Gotcha With StringFormat In WPF

This article describes a problem when using the StringFormat UpdateSourceTrigger property set to PropertyChanged in WPF.

(The source code is attached.)

I hope you have used the StringFormat property on your binding to render the formatted value on the user interface. But are you aware one of its secret? Well before revealing that secret, let's have a look at how StringFormat works with binding.

Scenario problem: I am taking an example scenario, in which my text box will display an amount to three decimals.

Now there are multiple ways to do this. One way can be to use Converters and another way can be to use a StringFormat along with TextBox binding. Perhaps there can be more ways apart from these two. ;)
In the following sample I will use the StringFormat trick to do this and code to perform this operation is very straight forward as in the following:

<TextBox Text="{Binding Amount,StringFormat=f3}" />

With the code above, whenever you lose focus from your TextBox, the given amount will be displayed as three decimal points. Until here everything is perfect as expected but with one downside.

Important point on StringFormat

What one sees on the screen is not the actual value that will be stored; that can be different from the underlined value. But if this is really a requirement of what we want to show to the user then it's up to the developer to manage such inconsistencies.

Gotcha with StringFormat

Now is the time came to reveal that gotcha. If you want to add the UpdateSourceTrigger property = PropertyChanged along with your StringFormat, then guess what will happen?

Code

<TextBox Text="{Binding Amount, UpdateSourceTrigger=PropertyChanged, StringFormat=f3}"/>

To understand this issue, let's go step-by-step.

Step 1: Run the application and you will get the following output.

StringFormat

Step 2: Enter the value in the text box as 35.45. You will get the following screen:

textbox

Explanation: Please note, you have applied UpdateSourceTrigger=PropertyChanged. So, as soon as you hit a keyboard key, immediately StringFormat will be called due to the change in the target property and sets the underlined source property. Our source property raises a PropertyChanged event that forces the binding to re-bind and re-render based on the StringFormat.

The problem occurs with fast input scenarios as shown in the screenshot above and you will end up with the red rectangle.

Reason: After each key stroke, it is re-rendering the value of text box.

Step 3: Click on the Save button to cause the focus to be lost from the text box as shown below:

button

Explanation: As per the StringFormat property, the text box should be able to change the value to the required precession. But it doesn't happen.

Reason: Due to UpdateSourceTrigger=PropertyChanged

Hence, one should avoid using UpdateSourceTrigger=PropertyChanged with StringFormat, due to this re-rendering issue.