¿Cómo puedo formatear un decimal vinculado a TextBox sin enojar a mis usuarios?

Estoy intentando mostrar un decimal formateado en un TextBox usando el enlace de datos en WPF.

Metas

Objetivo 1: Al configurar una propiedad decimal en el código, muestre 2 lugares decimales en el Cuadro de texto.

Meta 2: Cuando un usuario interactúa con (escribe) el TextBox, no lo fastidies.

Objetivo 3: Los enlaces deben actualizar la fuente en PropertyChanged.

Intentos

Intento 1: No hay formato.

Aquí estamos empezando casi desde cero.

<TextBox Text="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}" />

Viola el gol 1.SomeDecimal = 4.5 mostrará "4.50000" en el cuadro de texto.

Intento 2: Usa StringFormat en el enlace.

<TextBox Text="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}" />

Infrinja el objetivo 2. Diga que el valor de algunos es de 2.5 y el cuadro de texto muestra "2.50". Si seleccionamos todos y escribimos "13.5", terminamos con "13.5.00" en el TextBox porque el formateador "útilmente" inserta decimales y ceros.

Intento 3: usar el cuadro de herramientas de WPF ampliado MaskedTextBox.

http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox

Suponiendo que estoy leyendo la documentación correctamente, la máscara ## 0.00 significa "dos dígitos opcionales, seguidos de un dígito requerido, un punto decimal y otros dos dígitos requeridos. Esto me obliga a decir" el número más grande posible que puede ingresar. este TextBox es 999.99 "pero digamos que estoy bien con eso.

<xctk:MaskedTextBox Value="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}" Mask="##0.00" />

Viola el gol 2. El cuadro de texto comienza con___.__ y seleccionándolo y escribiendo 5.75 rendimientos.575.__. La única forma de obtener 5.75 es seleccionar el TextBox y escribir<space><space>5.75.

Intento 4: use el spinner DecimalUpDown del Kit de herramientas WPF extendido.

http://wpftoolkit.codeplex.com/wikipage?title=DecimalUpDown

<xctk:DecimalUpDown Value="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}" FormatString="F2" />

Infringe el objetivo 3. DecimalUpDown ignora alegremente UpdateSourceTrigger = PropertyChanged. Uno de los coordinadores en la página del paquete de herramientas WPF extendido Codeplex sugiere una plantilla de control modificada enhttp://wpftoolkit.codeplex.com/discussions/352551/. Esto satisface el Objetivo 3, pero viola el Objetivo 2, exhibiendo el mismo comportamiento que en el Intento 2.

Intento 5: utilizando los controladores de datos de estilo, solo use el formato si el usuario no está editando.

Enlace a un doble con StringFormat en un TextBox

Incluso si este cumple con los tres objetivos, no me gustaría usarlo. (A) Los cuadros de texto se convierten en 12 líneas cada uno en lugar de 1, y mi aplicación contiene muchos, muchos cuadros de texto. (B) Todos mis cuadros de texto ya tienen un atributo de Estilo que apunta a un StaticResource global que establece Margen, Altura y otras cosas. (C) Es posible que haya notado que el siguiente código establece la ruta de enlace dos veces, lo que viola el principal DRY.

<TextBox>
    <TextBox.Style>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Text" Value="{Binding Path=SomeDecimal, StringFormat=F2}" />
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="Text" Value="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>

Todas estas cosas incómodas a un lado ...

Infrinja el objetivo 2. Primero, al hacer clic en un cuadro de texto que muestra "13.50", de repente aparece "13.5000", lo cual es inesperado. Segundo, si comienza con un TextBox en blanco, y escribo "13.50", el TextBox contendrá "1350". No puedo explicar por qué, pero al presionar la tecla de período no se insertan decimales si el cursor está en el extremo derecho de la cadena en el cuadro de texto. Si el TextBox contiene una cadena con longitud> 0, y reposiciono el cursor en cualquier lugar excepto el extremo derecho de la cadena, puedo insertar puntos decimales.

Intento 6: hazlo yo mismo.

Estoy a punto de embarcarme en una gran cantidad de dolor y sufrimiento, ya sea haciendo una subclase de TextBox, o creando una propiedad adjunta, y escribiendo el código de formato yo mismo. Estará lleno de manipulación de cuerdas y causará una pérdida de cabello considerable.

¿Alguien tiene alguna sugerencia para formatear decimales vinculados a cuadros de texto que satisfagan todos los objetivos anteriores?

Respuestas a la pregunta(3)

Su respuesta a la pregunta