Q:

WPF: formatting textbox input as user types

In our WPF application, there are several textboxes where users ought to input only currency. It's easy to force the textbox to format the input as it goes in:
<TextBox Text="{Binding CostOut, StringFormat='{}{0:C}' />

However, this formats so quickly that it causes unexpected effects to the user as the text is type, because the numbers before and after the decimal seem to be treated almost as separate fields. 
To counter this, we added a delay:
<TextBox Text="{Binding CostOut, StringFormat='{}{0:C}', Delay=1000  />

Which worked better as most people had finished typing before their numbers got formatted. However, the application is complex and deals with important financial data, and some users think carefully about the numbers as they're typed. For these slow typers, this delay still caused their input to get reformatted mid-type.
I'm unwilling to go further down the "delay" route as we'll eventually get to a point where it doesn't get formatted before someone saves. I found and tried a WPF CurrencyTextBox which was rejected as a solution because the "cash register" style typing was too unfamiliar.
Currently the proposed solution is to remove all formatting from the application and format only on save. This feels drastic to me, and I can't help wondering if there's a better solution?

A:

You could try setting the desired format when the textBox loses it's focus on the LostFocus event of your textBox. It'll allow the user to type as long as he/she has to, and won't be as drastic as to format it on the save button.

A:

As mentioned in a comment I've created a small example on how to bind the LostFocus-Event to a ICommand-property in your ViewModel.
The attached-property looks like:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace TextBoxLostFocusBehaviorExample
{
    internal static class TextBoxExtensions
    {
        public static readonly DependencyProperty LostFocusCommandProperty = DependencyProperty.RegisterAttached(
            "LostFocusCommand",
            typeof(ICommand),
            typeof(TextBoxExtensions),
            new PropertyMetadata(default(ICommand), OnLostFocusCommandChanged));

        private static void OnLostFocusCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TextBox textBox = d as TextBox;
            if (textBox == null)
            {
                return;
            }

            if (e.NewValue != null)
            {
                textBox.LostFocus += TextBoxOnLostFocus;
            }
        }

        private static void TextBoxOnLostFocus(object sender, RoutedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox == null)
            {
                return;
            }

            ICommand command = GetLostFocusCommand(textBox);
            command.Execute(null);
        }

        public static void SetLostFocusCommand(DependencyObject element, ICommand value)
        {
            element.SetValue(LostFocusCommandProperty, value);
        }

        public static ICommand GetLostFocusCommand(DependencyObject element)
        {
            return (ICommand)element.GetValue(LostFocusCommandProperty);
        }
    }
}

In your ViewModel you then have a property of type ICommand which can look like:
private ICommand lostFocusCommand;
public ICommand LostFocusCommand
{
    get { return lostFocusCommand ?? (lostFocusCommand = new RelayCommand(p => CostOutLostFocus())); }
}

And the CostOutLostFocus-Method will be called when the LostFocus-Event is triggered.
The usage of the attached property in the view looks like:
<TextBox Text="{Binding CostOut, Mode=TwoWay}" TextBoxLostFocusBehaviorExample:TextBoxExtensions.LostFocusCommand="{Binding LostFocusCommand}"/>

TextBoxLostFocusBehaviorExample is the namespace where the class of the attached property is defined.

