Maskedtextbox in WPF implementieren
Heute beschreibe ich mal, wie man in WPF ein Control erstellt, dass von TextBox erbt und die Funktionalität einer Maskedtextbox bietet. Als ich vor kurzem diese Funktionalität brauchte hat sich herausgestellt, dass das ganze innerhalb von kurzer Zeit erledigt werden kann.
- Zunächst erzeugt man in Visual Studio ein entsprechendes Projekt mit der Vorlage WPF-Benutzersteuerelementbibliothek.
- In diesem Projekt kann man das automatisch erzeugte UserControl1 guten Gewissens entfernen (wir wollen ja ein WPF-Steuerelement erstellen).
- Dafür muss man unser WPF-Steuerelement hinzufügen. (Einfügen –> neues Element –> Benutzersteuerelement)
- Jetzt geht es darum, aus dem Usercontrol ein Steuerelement zu machen, welches von der Standard-TextBox erbt, damit man die ganzen Standard Geschichten schon fertig hat. Dazu einfach im XAML-Code UserControl durch TextBox ersetzen, und alle Attribute außer den namespaces und dem Klassennamen entfernen, so dass es in etwa so ausschaut:
<TextBox x:Class="Denis.WPF_Controls.MaskedTextBoxWPF" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
Dadurch sagen wir einfach, dass wir ein Steuerelement erzeugen dass von TextBox erbt. Da es ja auch noch eine entsprechende CodeDatei gibt müssen wir dort ebenfalls sagen, dass wir nicht mehr die partielle Klasse UserControl erweitern, sondern Textbox:
public partial class MaskedTextBoxWPF : UserControl //ersetzen durch public partial class MaskedTextBoxWPF : TextBox
- Jetzt brauchen wir noch ein paar Events die wir behandeln um abzufangen wenn Text eingegeben, gelöscht und eingefügt (copy/paste) wird. Dazu einfach den XAML-Code so erweitern:
<TextBox x:Class="Denis.WPF_Controls.MaskedTextBoxWPF" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DataObject.Pasting="TextBox_Pasting" PreviewTextInput="TextBox_PreviewTextInput" KeyDown="TextBox_KeyDown" />
- Als erstes brauchen wir eine Klassen-Variable, welche den MaskedTextBoxProvider enthält (wofür ein Verweis auf SystemComponentModel benötigt wird). Diese wird dann im Konstruktor mit einer Standardmaske gefüllt und dann initialisiert:
MaskedTextProvider mktProvider; public MaskedTextBoxWPF() { InitializeComponent(); mktProvider = new MaskedTextProvider("???"); }
- Außerdem geben wir die Mask-Eigenschaft nach außen weiter, lassen die im Designer bearbeiten und geben auch ne kleine Doku für das Bearbeiten im Designer an:
[Browsable(true)] [DesignOnly(true)] [Description("0 Ziffer - erforderlich; 9 Ziffer oder Leerzeichen - opt.;" + "L Buchstabe - erforderlich; ? Buchstabe - opt.")] public string Mask { get { return mktProvider.Mask; } set { mktProvider = new MaskedTextProvider(value); Text = ""; } }
- Als letztes müssen wir noch die Events mit Code füllen.Im PreviewTextInput-Ereignis prüfen wir, ob der Buschstabe hinzugefügt werden darf und brechen ggf. ab.Im Pasting-Ereignis machen wir das selbe mit eingefügtem Text und das KeyDown-Ereignis ist dafür da den Text im MaskedTextBoxProvider aktuell zu halten (falls z.B. was gelöscht wird).
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { if (mktProvider.Add(e.Text) == false) { e.Handled = true; } } private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(typeof(String))) { String text = (String)e.DataObject.GetData(typeof(String)); if (mktProvider.Add(text) == false) { e.CancelCommand(); } } else e.CancelCommand(); } private void TextBox_KeyDown(object sender, KeyEventArgs e) { mktProvider.Clear(); mktProvider.Add(Text); }
So, das war’s schon. Man könnte das ganze noch etwas schöner machen, indem man wie bei WinForms die Eingabemaske anzeigt, aber die Funktionalität ist vorhanden und kann so benutzt werden.



danke! hab genau sowas gesucht!
don’t reinvent the wheel…