Suppose you typed 01 into the textbox. If you then entered a decimal point '.' the exact text contained in the textbox would be "01.", which is not valid according to your regular expression.
You might try tweaking the regex a bit:
Code:
Instead of:
@"^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9])?$"
Maybe:
@"^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9]{0,2})?$"
^---------^
That should allow an input of "01." or "01.1", or "01.11", up to two decimal places.
As an alternative, instead of handling the key event and preventing the text from being entered, you might instead change the background color of the textbox to a color that indicates an error (Color.MistyRose maybe?)
Then, in the future, you don't have to worry about a complicated regular expression locking out your ability to type in a valid string. Sometimes you may have to type in something invalid in order to get to a valid state.
If, for example, you were to try the same approach with a phone number it probably wouldn't work. Surely you have to type something like "(368)" before you continue entering the rest of the phone number, but that obviously isn't a valid phone number on its own.
You might also want to look at the MaskedTextBox, which can do the same thing, only it doesn't use regular expressions.