Wie kann ich eine an TextBox gebundene Dezimalzahl formatieren, ohne meine Benutzer zu verärgern?

Ich versuche, eine formatierte Dezimalstelle in einer TextBox mithilfe der Datenbindung in WPF anzuzeigen.

Tore

Ziel 1: Zeigen Sie beim Festlegen einer Dezimalstelle im Code 2 Dezimalstellen im Textfeld an.

Ziel 2: Wenn ein Benutzer mit der TextBox interagiert (sie eintippt), ärgern Sie ihn nicht.

Ziel 3: Bindungen müssen die Quelle in PropertyChanged aktualisieren.

Versuche

Versuch 1: Keine Formatierung.

Hier fangen wir fast von vorne an.

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

Verstößt gegen Ziel 1.SomeDecimal = 4.5 wird "4.50000" in der Textbox anzeigen.

Versuch 2: Verwenden Sie StringFormat in der Bindung.

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

Verstößt gegen Ziel 2. Sagen Sie SomeDecimal ist 2.5 und das Textfeld zeigt "2.50" an. Wenn wir alle auswählen und "13.5" eingeben, erhalten wir in der TextBox "13.5.00", da der Formatierer "hilfreich" Dezimalstellen und Nullen einfügt.

Versuch 3: Verwenden Sie die MaskedTextBox von Extended WPF Toolkit.

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

Angenommen, ich lese die Dokumentation korrekt, bedeutet die Maske ## 0.00 "zwei optionale Ziffern, gefolgt von einer erforderlichen Ziffer, einem Dezimalpunkt und zwei weiteren erforderlichen Ziffern. Dies zwingt mich zu" der größtmöglichen Zahl, die eingegeben werden kann Diese TextBox ist 999,99 ", aber sagen wir mal, ich bin damit einverstanden.

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

Verstößt gegen Ziel 2. Die TextBox beginnt mit___.__ und wählen Sie es und geben Sie 5,75 Erträge575.__. Die einzige Möglichkeit, 5.75 zu erhalten, besteht darin, das Textfeld und den Typ auszuwählen<space><space>5.75.

Versuch 4: Verwenden Sie den DecimalUpDown-Drehregler des Extended WPF Toolkit.

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

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

Verstößt gegen Ziel 3. DecimalUpDown ignoriert UpdateSourceTrigger = PropertyChanged. Einer der Koordinatoren auf der Seite Extended WPF Toolkit Codeplex schlägt eine geänderte ControlTemplate unter vorhttp://wpftoolkit.codeplex.com/discussions/352551/. Dies entspricht Ziel 3, verstößt jedoch gegen Ziel 2 und zeigt dasselbe Verhalten wie in Versuch 2.

Versuch 5: Verwenden Sie Formatierungs-Datentrigger nur, wenn der Benutzer keine Bearbeitung ausführt.

Binden an ein Double mit StringFormat in einer TextBox

Selbst wenn dieser alle drei Ziele erfüllen würde, würde ich ihn nicht verwenden wollen. (A) Aus Textfeldern werden 12 Zeilen anstatt 1, und meine Anwendung enthält viele, viele Textfelder. (B) Alle meine Textfelder haben bereits ein Style-Attribut, das auf eine globale StaticResource verweist, mit der Rand, Höhe und andere Dinge festgelegt werden. (C) Möglicherweise haben Sie bemerkt, dass der folgende Code den Bindungspfad zweimal festlegt, was gegen den DRY-Prinzipal verstößt.

<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>

All diese unangenehmen Dinge beiseite ...

Verstößt gegen Ziel 2. Wenn Sie auf ein Textfeld klicken, auf dem "13.50" angezeigt wird, wird plötzlich "13.5000" angezeigt, was unerwartet ist. Zweitens, wenn Sie mit einer leeren TextBox beginnen und "13.50" eingeben, enthält die TextBox "1350". Ich kann nicht erklären, warum, aber durch Drücken der Punkt-Taste werden keine Dezimalstellen eingefügt, wenn sich der Cursor am rechten Ende der Zeichenfolge in der Textbox befindet. Wenn die TextBox eine Zeichenfolge mit einer Länge> 0 enthält und ich den Cursor an einer anderen Stelle als dem rechten Ende der Zeichenfolge positioniere, kann ich Dezimalstellen einfügen.

Versuch 6: Mach es selbst.

Ich bin dabei, eine Reise voller Schmerzen und Leiden zu beginnen, indem ich entweder TextBox untergeordnet oder eine angehängte Eigenschaft erstellt und den Formatierungscode selbst schreibe. Es wird voll von Saitenmanipulation sein und erheblichen Haarausfall verursachen.

Hat jemand Vorschläge zum Formatieren von Dezimalstellen, die an Textfelder gebunden sind, die alle oben genannten Ziele erfüllen?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage