Geeks With Blogs
The Quandary Phase This code was generated by a tool.

Rather a long gap between my last post and this...v. poor effort, must try harder.

Actually, I have been working on a project which involves a good deal of WPF, so have been busily getting to grips with its finer points, so not had much to post in the way of interesting information, and quite a lot of reading other people's blogs for what interesting information I could myself misappropriate...sorry, err...I mean absorb.

Well, it turned out we needed a MaskedTextBox control, which is conspicuously missing from the current WPF control set. We didn't need anything as flexible as the Windows Forms one- just one that would allow us to constrain the entering of such format-dependent strings as time, bank account numbers, sort codes etc.

This I achieved by inheriting from the WPF TextBox, and overriding the OnPreviewKeyDown and OnPreviewTextInput methods. The former is invoked OnKeyDown, as you would expect, and the latter when a keypress results in a character which will be appended or inserted at the current caret position.

I exposed a dependency property of string type representing the current input mask, then hooked up the property changed event, repopulating a collection of objects (one for each character in the input mask) which encapsulate the validation rules for the corresponding character position in the textbox.

The input mask syntax itself is very simple; it allows input to be constrained in 4 different ways, each indicated by a different placeholder character in the mask string (much like the Windows Forms equivalent, albeit much simplified). The 4 placeholder characters are:

  • i - allows integers only.
  • d - allows decimals only (i.e. integers, plus a single decimal point)
  • a - allows alphabetic characters only (i.e. a-z, A-Z)
  • w - allows alphanumeric characters only (i.e. a-z, A-Z, 0-9)

Everything in the input mask which is not one of the above characters is treated as a literal by the control, and therefore permanently visible in the input textbox, and not erasable.

So, taking one of the input field types mentioned above: the input mask for a date would look like this:

ii:ii

Which indicates two sets of 2-integer numbers, separated by a colon.

Note that this does not prevent the user from entering an invalid date-- they could still enter 99:99, and the textbox would allow it, but for my purposes, I am not interested in ensuring users enter a valid value- this will be picked up by the validation, which occurs later. The purpose of this control was simply to ensure that the input is correctly formatted.

Of course, there are all kinds of other options you could add in terms of input mask flexibility, and the windows forms control is a very good example of a much richer input mask feature set, but this control fulfills my current requirements, and is readily extensible. That said, I would imagine that an official WPF masked textbox will most likely be released with the next version of WPF, which will render this entirely redundant!

In the meantime, you can download the control's source code using the link above.

Edit (9/1/2009) : I have uploaded version 1.2 of the source code which addresses a few bugs in the initial version, in particular allowing the control to work in data binding scenarios.

Edit (12/2/2009) : Version 1.3 of the source code uploaded which fixes a minor text input bug in version 1.2, caused by some odd behaviour in the Text_CoerceValue method.

Posted on Wednesday, December 17, 2008 11:46 AM | Back to top


Comments on this post: WPF Masked TextBox

# re: WPF Masked TextBox
Requesting Gravatar...
Hi,

Good example...!

It will be great if you can also focus on following some queries.
I want to masked wpf textbox in a way that it should act like ip address control, the mask is 990.990.990.990 and i want to achieve from it standard windows ip control navigation/vaidation behavior like-

1)The bottom mask line should not appear.
2)The cursor position should always be in middle of the octet portion and if you do not type anything and leave it as it is i.e. blank and press arrow keys it should go to neighbouring octets
3)Validation should fire when we move out of octet having value more than MaxValue defined (say 255)
4)Each octet should be center-aligned.
5)Select first octet when the masked textbox get in focus.
Left by Harshal on Feb 17, 2009 12:30 PM

# re: WPF Masked TextBox
Requesting Gravatar...
Nice control - clean, simple & easy to use.
Left by Skip on Aug 05, 2009 1:08 PM

# re: WPF Masked TextBox
Requesting Gravatar...
Where is the link to download Source Code?
Left by Gaurav on Sep 02, 2009 9:22 AM

# re: WPF Masked TextBox
Requesting Gravatar...
@Gaurav: It's at the top of the article. But if you have iFrames disabled, your browser won't display it. Here's the full URL:

http://cid-960f9db28d749b11.skydrive.live.com/self.aspx/.Public/Code/Boo.MaskedTextBox.zip
Left by adampooler on Sep 02, 2009 9:38 AM

# re: WPF Masked TextBox
Requesting Gravatar...
Great job!!!
Left by Ruchika Rana on Sep 21, 2009 6:59 AM

# re: WPF Masked TextBox
Requesting Gravatar...
Hi,
Thanks for the tool.

There is a small bug but important for integer, it is about cultures.
In Turkish language if you make "i" ToUpper() it converts string to "İ" not "I". So conversion line should be as following in the switch.
character.ToString().ToUpper(CultureInfo.CreateSpecificCulture("en"))
Left by Usame Esendir on Feb 03, 2010 11:58 PM

# re: WPF Masked TextBox
Requesting Gravatar...
I create a MaskedText Behavior you can find here: http://blindmeis.wordpress.com/2010/06/01/wpf-masked-textbox-behavior/

Maybe it's a good alternative
Left by blindmeis on May 31, 2010 9:40 PM

# re: WPF Masked TextBox
Requesting Gravatar...
Hi! Very nice control, it can do exactly what i need (i needed to input passport serial number in special format).

You wrote that data binding scenarios are available now, but i tried using it - and it cannot display initial value of field it is bound to. It shows mask-value instead ( __:__ for example, from your sample) But saves value, that was just input - fine. Here is how i used the control.

<Control:MaskedTextBox InputMask="iiii_iiiiii" Text="{Binding Path=PassportSerialNumber, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />

What is my problem? Thank you.
Left by opposer on Sep 12, 2010 9:27 PM

# re: WPF Masked TextBox
Requesting Gravatar...
Hi

Great work, but it seems buggy if you use the End key on the keyboard and then backspace. Sometimes it will delete the mask itself. However after the mask is deleted it will come back ok once you start writing again. Just to let you know...
Left by Small bug on Nov 12, 2010 3:40 AM

# re: WPF Masked TextBox
Requesting Gravatar...
I really enjoyed the article. It proved to be very useful to me and I am sure to all the commenters here! It's always nice when you can not only be informed, but also entertained! I'm sure you had fun writing this article.
Left by Indonesian Teak Furniture on Dec 07, 2010 5:16 AM

Comments have been closed on this topic.
Copyright © Adam Pooler | Powered by: GeeksWithBlogs.net