WPF-so erstellen Sie ein Benutzerdefiniertes Textfeld mit Validierung und-Bindung
Entwickle ich ein custom text Feld für Währung Bearbeiten.
Ich habe gesehen, einige bereit sind zu verwenden sind, aber Sie sind kompliziert und/oder nicht wirklich brauchbar, Sie zu zwingen, schlechte Praktiken (wie der harte Codierung der name, der verwendet werden soll, auf die Steuerung).
Also habe ich beschlossen, es selbst zu tun, aber ich habe Probleme beim arbeiten mit dem binding-Optionen, da die Eigenschaft zugewiesen, um das binding-Attribut muss eine Dezimalzahl, aber die Text-Eigenschaft des TextBox-Steuerelements akzeptiert strings.
Die Antwort, die ich dachte, war, vielleicht, überschreiben Sie die access-Methoden (Getter und setter), um die Text-Eigenschaft in der Basisklasse (TextBox), aber es ist nicht erlaubt.
Meine Bindung eingestellt werden sollte, um den Wert, setzt die text-Eigenschaft des TextBox-Formatierung als text (mit der Währung Symbole und alles) unterwegs, aber Sie zu konvertieren zurück zu einem numerischen Datentyp auf der Get-Methode.
Dies ist, was ich bisher erreicht:
public class CurrencyTextBox : TextBox
{
private bool IsValidKey(Key key)
{
int k = (int)key;
return ((k >= 34 && k <= 43) //digits 0 to 9
|| (k >= 74 && k <= 83) //numeric keypad 0 to 9
|| (k == 2) //back space
|| (k == 32) //delete
);
}
private void Format()
{
//formatting decimal to currency text here
//Done! no problems here
}
private void FormatBack()
{
//formatting currency text to decimal here
//Done! no problems here
}
private void ValueChanged(object sender, TextChangedEventArgs e)
{
this.Format();
}
private void MouseClicked(object sender, MouseButtonEventArgs e)
{
this.Format();
//Prevent changing the caret index
this.CaretIndex = this.Text.Length;
e.Handled = true;
}
private void MouseReleased(object sender, MouseButtonEventArgs e)
{
this.Format();
//Prevent changing the caret index
this.CaretIndex = this.Text.Length;
e.Handled = true;
}
private void KeyPressed(object sender, KeyEventArgs e)
{
if (IsValidKey(e.Key))
e.Handled = true;
if (Keyboard.Modifiers != ModifierKeys.None)
return;
this.Format();
}
private void PastingEventHandler(object sender, DataObjectEventArgs e)
{
//Prevent copy/paste
e.CancelCommand();
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
//Disable copy/paste
DataObject.AddCopyingHandler(this, PastingEventHandler);
DataObject.AddPastingHandler(this, PastingEventHandler);
this.CaretIndex = this.Text.Length;
this.PreviewKeyUp += KeyPressed;
this.PreviewMouseDown += MouseClicked;
this.PreviewMouseUp += MouseReleased;
this.TextChanged += ValueChanged;
this.Format();
}
}
- und das ist der XAML-Code:
<MyNamespace:CurrencyTextBox x:Name="TxbCurrency" Text="{Binding Path=DataContext.Element.Currency, ValidatesOnDataErrors=True}" />
So weit, So gut! Die Bindung von dezimal-Eigenschaft der TextBox-text ist "Recht". Aber wie man die Dezimalzahl zurück aus dem text nach ist es eine Bearbeitung ist jetzt das problem.
Die Bindung von dezimal-zu-den .Text-Boxen zu verstecken die ToString () - Methode.
Frage:
Wie kann ich die überlastung der Parse () - Methode von dezimal in diesem Fall, um meine FormatBack () - Methode erhalten die Dezimalzahl, die aus den TextBox-Text?
- ich nehme an, damit der Benutzer geben Sie einen beliebigen text, auch wenn Streicher und, wenn Fokus verloren machen geltend machen, wenn er nicht hinzufügen, dezimal-Wert
- Ich denke, die Frage war nicht klar. Das problem mit der Bindung, die nicht mit der Formatierung Logik. Formatierung der text ist schon ok...
- wenn dies der Fall ist, erstellen Sie neue
Dependency Property
nennen es Wert und binden Ihre Währung an es
Du musst angemeldet sein, um einen Kommentar abzugeben.
erstellen neue
Dependency Property
wie diesebinden und anschließend zu dieser neuen Eigenschaft
Gut, für zukünftige Zwecke, wenn jemand hängen geblieben ist mit den gleichen Schwierigkeiten, hier ist der komplette code für die Währung Textfeld. Fühlen Sie sich frei, es zu benutzen, ändern Sie es, verkaufen Sie es (glaube nicht, dass es wertvoll, du), oder spielen Sie mit ihm so viel wie Sie wollen!
und xaml:
if(!this.IsFocused) this.Text = String.Format("{0:0.00}", value)
schauen Sie auf diese Artikel ich denke, es wird dir helfen.
http://www.codeproject.com/Articles/15239/Validation-in-Windows-Presentation-Foundation
oder Sie können diese
und in
PreviewTextInput
Veranstaltung dieserIch glaube nicht, dass dies tatsächlich möglich ist, außer für den einfachen Fall von einem Feld, dass nur Ziffern erlaubt. Idealerweise möchten Sie eine box, die nur eine gültige Angabe, sondern Dezimalzahlen enthalten, werden einige Zeichen (wie '-' und '.') nicht gültig auf Ihrer eigenen. Der Benutzer kann nicht starten durch die Eingabe von einem' -', ohne dass man die box in einem ungültigen Zustand.
Sie könnten auch geben Sie '1.', und dann löschen Sie die " 1 " und verlassen Sie die box in einem unbestimmten Zustand. Sicher, es verursacht einen Validierungsfehler an und einen roten Rand, aber dein view-model-immer noch glaubt, der Wert ist 1, und nicht auf das problem aufmerksam.
Für positive ganze zahlen sind, können Sie sich nur erlauben, Ziffern und einfügen automatisch eine null, wenn leer (obwohl das ein wenig unfreundlich)
Für Dezimalzahlen und negativen zahlen, ich denke, das beste, was Sie tun können, ist zu beschränken, die Tasten, die ein Benutzer eingeben kann, aber Sie noch brauchen, um die wrap your number-Eigenschaft in eine Zeichenfolge, und validieren Sie ihn - entweder, wenn die OK Schaltfläche gedrückt wird, oder im Idealfall implementieren INotifyDataError, um den Fehler anzuzeigen, und deaktivieren Sie die OK-Taste.