I found a new control for the AvalonControlsLibrary, the MaskedTextBox. I found this control while reading one of the best WPF books around from Matthew MacDonald.
The MaskedTextBox is a normal WPF textbox (in fact it inherits from the TextBox class) that formats the text entered by the user (and also strings set from the Text property programmatically). For example if you type 1234567890 into a masked textbox that has a U.S. telephone number mask, the text will be displayed as (123) 456-7890. To check out how you can create Masks have a look at this url.
To create this control I use the MaskTextProvider which is a .Net class. The MaskedTextProvider takes care of validating the string and also to format the text entered accordingly to the mask specified.
The MaskedTextBox has a Mask property which accepts a string. This string (and the mask property) is then used to create a MaskedTextProvider that can format the user input.
In order to intercept the user input, I override the OnPreviewTextInput method and apply the mask to the text that has been entered. As you can see this is 80% of the control’s code.
/// <summary>
/// override this method to replace the characters enetered with the mask
/// </summary>
/// <param name=”e”>Arguments for event</param>
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
int position = SelectionStart;
MaskedTextProvider provider = MaskProvider;
if (position < Text.Length)
{
position = GetNextCharacterPosition(position);
if (Keyboard.IsKeyToggled(Key.Insert))
{
if (provider.Replace(e.Text, position))
position++;
}
else
{
if (provider.InsertAt(e.Text, position))
position++;
}
position = GetNextCharacterPosition(position);
}
RefreshText(provider, position);
e.Handled = true;
base.OnPreviewTextInput(e);
}
I also override the OnPreviewKeyDown method of the TextBox in order to handle special characters such as delete and backspace.Yet we have a problem! The problem is that if the user uses cut or paste the mask will not be applied until the next keystroke. So the workaround (described in the book) shows us how we can use CommandBinding to suppress these features. I really liked the idea because this shows us how commands can give us such power in our hands. So to suppress these features we have to do the following///<summary>
/// Default constructor
///</summary>
public MaskedTextBox()
{
//cancel the paste and cut command
CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, null, CancelCommand));
CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, null, CancelCommand));
}
//cancel the command
private static void CancelCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
} As you can see all you have to do is handle the command yourself and just set the CanExecute to false and Handled to true. Nice!Another problem is how we can force the Text property to apply the Mask when set programmatically. Since we only handle the OnPreviewTextInput this is not catered for. And here comes the FrameworkMetaData. Basically we can override the default meta data for the Text property and apply a CoerceValueCallback that apply the mask to the text./// <summary>
/// Static Constructor
/// </summary>
static MaskedTextBox()
{
//override the meta data for the Text Proeprty of the textbox
FrameworkPropertyMetadata metaData = new FrameworkPropertyMetadata();
metaData.CoerceValueCallback = ForceText;
TextProperty.OverrideMetadata(typeof(MaskedTextBox), metaData);
}//force the text of the control to use the mask
private static object ForceText(DependencyObject sender, object value)
{
MaskedTextBox textBox = (MaskedTextBox) sender;
if (textBox.Mask != null)
{
MaskedTextProvider provider = new MaskedTextProvider(textBox.Mask);
provider.Set((string) value);
return provider.ToDisplayString();
}
else
{
return value;
}
} This shows us how powerful Dependency properties are. I was really excited about this one since it’s my first time to play around and override property meta data explicitly 🙂
And that’s basically it.Eventually I will implement a real MaskedTextBox by inheriting from the TextBoxBase but for now this will do the trick for developers that need this control.Hope you find this control useful.Downlaod control demo and full source code
Hi,
You made a little mistake, because if space is pressed the PreviewTextInput Event will not be raised, so you have to handle that in the PreviewKeyDown Event. Space is the only character of these special keys, which could valid for a mask.
So I wrote a little adaptation:
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
MaskedTextProvider provider = MaskProvider;
int position = SelectionStart;
if (e.Key == Key.Delete && position 0)
{
position–;
if (provider.RemoveAt(position))
RefreshText(provider, position);
}
e.Handled = true;
}
else if (e.Key == Key.Space)
{
if (provider.InsertAt(‘ ‘, position))
RefreshText(provider, position);
e.Handled = true;
}
}
Regards,
Martin
Sorry I had a problem to copy the code snipped,
so second try:
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
MaskedTextProvider provider = MaskProvider;
int position = SelectionStart;
if (e.Key == Key.Delete && position 0)
{
position–;
if (provider.RemoveAt(position))
RefreshText(provider, position);
}
e.Handled = true;
}
else if (e.Key == Key.Space)
{
if (provider.InsertAt(‘ ‘, position))
RefreshText(provider, position);
e.Handled = true;
}
}
Ok I dont know why but some parts of my code are cutted out by the blog…
Thanks a lot I will make sure to make this fix and upload the new code.
Thanks a lot
If anyone is having problems with the IsReadonly Property of this control please have a look here
http://www.codeplex.com/AvalonControlsLib/WorkItem/View.aspx?WorkItemId=860
The code for this fix is committed in CodePlex… The official release will be AvalonControlsLibrary V2
Thanks for the support
How to bind masked text box with today’s date.
I have written following xaml code but it dosent work
Kindly help
Your MaskedTextBox behaves different than the WinForms MaskedTextBox.
The ability to select a character and overwrite it is vital for masks like ‘L00’ that allow a letter and two digits.
If one enters X99 and wants to change it to Y99, this can be done with WinForms by selecting the X and typing a Y.
With your control the user probably will have to delete all three characters and type Y99 (one cannot delete the X from X99 because a digit would move into the letter position of the mask string).
Hi, I am not very sufficient in C# and If anyone can help me that would be the great. The question is:
Write the mask for a masked Textbox that can produce “(AB)-(2)-(888)” as a possible output.
Hi Marlon,
Thanks for the very useful control of yours.
I am using the MaskedTextBox in one of our projects.
I need to disable the Mask from appearing on the textbox by default(the mask should appear when the control gets focus)
Second is, the textbox should be able to accept Space when the Mask is to ‘CCCCCCCC’.
Thanks in advance,
Prudhvi.
brilliant post about a MaskedTextBox for WPF here
http://wekempf.spaces.live.com/blog/cns!D18C3EC06EA971CF!508.entry
Will you include the attached property masked textbox functionality as an alternative implementation in your AvalonControlsLibrary?
Good, but I think this way is easier :
http://msdn.microsoft.com/en-us/library/system.windows.forms.integration.windowsformshost(VS.85).aspx
It may be easier but it depends what you want to do…. Since this control is 100% WPF you can do anything you want with it… (control templates etc…)
So I guess it is just a matter of what you want to do…
Hi All,
We are using masked wpf textbox (from avalon control library) and is masked to 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) Ctrl + arrow keys and ‘.’ should select/navigate to neighbouring octet as in standard windows ip control
2) On TAB key press focus should leave the control. In my case it is going to next textbox in the sequence.
3) The bottom mask line should not appear.
4) Validation should fire when we move out of octet having value more than 255
5) 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 will go to neighbouring octets and each octet version should be center-aligned.
6) Select first octet when the masked textbox get in focus.
Would it be fairly complex to do this kind of stuff ?
If not please suggest me how to achieve this features.
Thanks in advance.
Anurodh
This example (and the latest code for the AvalonControlsLibrary) does not work how I would expect it to. Especially when comparing it to the winform masked textbox.
Lets say you have a string property (call it MyTime) bound to this control. The xaml looks like so.
MyTime is just a string property on the codebehind or whatever you are using as a DataContext.
The second textbox is also bound to that property, this is just for viewing what is actually set on the bound property.
Now, the Mask is “90:00” which means the first digit is optional and could be a space, the rest of the fields are required digits.
If i enter 2:33 into the textbox, the masked textbox shows “_2:33” and the second (unmasked) textbox bound to the same property shows “_2:33”.
This is not what I would expect, shouldn’t the bound value be “2:33”? I would not expect the mask placeholders to be returned when I try to get the value of .Text. If I’m using this control, and I have optional elements in my mask, I don’t want to have to strip out extraneous underscores from my result.
Compare this to the winform masked textbox, using the same mask. If I enter 2:33, and I examine the .Text property of the control via a breakpoint, it returns me “2:33”, not “_2:33”.
I’ve tried to remedy this, but cannot quite seem to get it. I could add a separate property to get the value I want, but I feel like it should work just using the .Text binding.
Perhaps the author or someone else has an idea?
sorry, xaml didn’t come through the filter, you can view it here.
http://dl.getdropbox.com/u/78912/xamlexample.txt
The MaskedTextBox does not inherit the default style as the rest of the controls on a page. Also, it has no header / label- you have to create a compound control for it.
Any ideas why this is the case?
I’m facing a problem using it when i bind a property to Text.. like this:
The mask is shown correctly, but after i type my date, and go to next control, the date disappear!
i am using MaskedTextBox for phone numbers
but on saving the value i want to take the original text not the formatted one ,any ideas about how to do it??
Pingback: WPF – Masked Textbox Behavior | Blindmeis's Blog
I must say you have a cool post. This hit the spot and then some! Thanks for posting this and sharing it with the world. I�ve just bookmarked your site. And I will check back soon to read your other articles. Keep up your awesome work.
I’ve eventually located a standard presentation on this challenge. Thank you
What would it take for this to support Copy and Paste?
Thank you very much for the providing this article.
It’s actually a great and helpful piece of info. I’m satisfied that you simply shared this useful info with us. Please keep us up to date like this. Thank you for sharing.
Pingback: Contrôles manquants en WPF | Blog de JP Gouigoux
Very nice article. I really enjoyed it reading. And it also cleared lot of my doubts about MaskedTextbox control in C#.Net, Very useful information, its really helpful for me. Check this link too its also having nice post with wonderful explanation.
http://www.mindstick.com/Articles/29af393c-5a6e-4f18-92af-da89b0f8eae4/?MaskedTextBox%20Control%20in%20C#.Net
Thanks for your wonderful post.
I personally wanted to show this specific blog, “Masked TextBox C# Disciples”
with my personal close friends on fb. I reallyjust simply desired to spread your very
good posting! Thank you, Francisco
I’m curious to find out what blog system you have been utilizing? I’m having some small security issues with my latest
blog and I would like to find something more safe.
Do you have any suggestions?
Thank you for the good writeup. It in reality
was a amusement account it. Look advanced to more introduced agreeable from you!
However, how could we keep up a correspondence?
My developer is trying to persuade me to move to .
net from PHP. I have always disliked the idea because of the expenses.
But he’s tryiong none the less. I’ve been using WordPress on several websites for about a year and am
nervous about switching to another platform. I have heard excellent
things about blogengine.net. Is there a way I can import
all my wordpress posts into it? Any help would be really appreciated!
Thanks for the auspicious writeup. It in reality used to be a enjoyment account it.
Glance advanced to more delivered agreeable from you!
By the way, how can we keep in touch?
I was wondering if you ever considered changing
the page layout of your site? Its very well written; I love what youve
got to say. But maybe you could a little more in the way of content so people could connect with it better.
Youve got an awful lot of text for only having one or 2 images.
Maybe you could space it out better?
Yesterday, while I was at work, my sister stole my apple ipad and tested to see if it can survive a forty foot drop, just so she can be a youtube sensation.
My iPad is now broken and she has 83 views. I know
this is completely off topic but I had to share it with someone!
“Masked TextBox | C# Disciples” certainly got me personally simply hooked with ur internet page!
I actuallywill probably wind up being returning considerably more regularly.
Thanks -Ted
I love what you guys are usually up too. This sort of clever work and coverage!
Keep up the amazing works guys I’ve incorporated you guys to blogroll.
e liquid Masked TextBox | C# Disciples
Apart from the high quality products this highly
reputed web storee also allows thhe client to
get his favorite fashion item at an affordable by using Freecultr coupon code.
We offer a career in vogue design in a variety of various fields.
s preferences using a commercial state of mind and voila you will possess landed yourself in marketing fashion operate in no
time.
Foods, including snack crackers, are either organic or not.
The Chivas series (named after Mexican club CD Chivas Guadalajara) is on the feet of about one-third of my
players. Cursing on the playing field is ill-advised, unless
all players agree that cursing is allowable.
When I originally commented I clicked the “Notify me when new comments are added” checkbox and
now each time a comment is added I get several emails with the same comment.
Is there any way you can remove me from that service? Cheers!
I personally have quite a number of hobbies which include card-making, fishing, gardening, baking, preserving,
jewellery making, jigsaws, collecting salt & pepper shaker sets and papertole.
If you want to see what all the fuss is about, try slipping into some
fur and experiencing the “tangible luxury” of these coats.
If you act like a man who can have his pick of women, then chances are, you
will.
Perhaps up to now any time you were forced to rely upon main points in your own local shop
you can actually, the difference is days available to get swimwear
on loads of various websites online, solely allowed research one and turn not really over joyed when using the swimwear you have got.
This ensures that they are incredibly supportive as well as having a lot of versatility.
Hence, a very important to establish the right bathing suit for each various outing.
The needs for Protyein is greater att certain stags of life, like during adolesecense each time a person is
growing, or when a person is dealing with an illness or accident.
As with any food, some dogs might have an intolerance but generally speaking, garlic and nutritional yeast
are incredibly good for dogs. 35 minute per mile pace will
burn approximately 12.
Hey! This is my first visit to your blog! We are a collection of volunteers and starting a new project in a community in the
same niche. Your blog provided us valuable information to work on. You have done a wonderful job!
I have been exploring for a little bit for any high quality articles or blog posts in this kind of
house . Exploring in Yahoo I ultimately stumbled upon this
web site. Reading this info So i’m satisfied to express that I’ve an incredibly just right uncanny feeling I came upon just what I needed.
I most without a doubt will make sure to do
not put out of your mind this website and provides it a glance regularly.
it will be extremely secure in the coming years. Armenia might possibly be the logical territory for freestaking.com to be utilized
Jetzt wehrt sie sich und macht die Nachrichten ihrer Verehrer und Neider unter dem vielsagendem Pseudonym perv_magnet
(etwa „Magnet für Perverse) öffentlich.
Thank You
Dies alles sind Inhaltsstoffe, die bei einer ausgewogenen und gesunden Ernährung nicht fehlen dürfen.
Für Sparfüchse hat Fitbit das günstige Zip im Angebot , bei dem ihr jedoch ohne Schlafüberwachung
auskommen müsst.
What’s up every one, here every one is sharing such
experience, so it’s pleasant to read this webpage, and I used to pay
a quick visit this web site daily.
I do acceрt as true with all of the ideas you’ve presentеd in your post.
They are very convincing and can certainly work.
Still, the posts are verу quick for starters. May you please ⅼengthen them a bit fгom sᥙbsequᥱnt
time? Thanks for the post.
Riǥht noա it looks like Druρal іѕ the toр blogging pⅼatform avaіlable right now.
(from what I’ve read) Is that what you’re using on your blog?
I’ve read several eхcellent stuff here. Certainly value
ƅookmarking for reviѕiting. I wonder hoա a lot
effort yoᥙ set to mаkе this kind of wоnderfuⅼ informative site.
This is my fіrst time pay a visit at here and i am rеally һappy to read all
at one plaсe.
What’s up to every body, it’s my first pay a quick visit of this blog; this webpage carries remarkable and actually good information for visitors.
Pingback: Create WPF TextBox that accepts only numbers [duplicate] – w3toppers.com