When using textbox.Undo(); I get the following error:
Cannot Undo or Redo while undo unit is open.
Now I understand why this is
To answer simbay's approach, which I think is being dismissed.
You can't call Undo in TextChanged because the undo operation is still being prepared by the TextBox. It seems to work sometimes and not other times, so this suggests there is a race condition between when the event is signaled and the completion of the undo preparation.
However calling Undo invoked on the Dispatcher will allow the text box to complete its undo preparation. You can validate the results of the text change and then decide if you want to keep or undo the change. This may not be the best approach, but I tried it and blasted a bunch of text changes and pastes into the text box and could not reproduce the exception.
The "accepted answer" is great ONLY if you want to prevent an invalid character from being entered or pasted, but in general I often do a lot more involved validation of TextBox input and want to verify the final text value. Its not easy to discern the final text from a Preview event because as far as the control is concerned nothing has happened yet.
To answer Terribad's question, simbay's answer is better and more succinct in more situations.
tb.TextChanged += ( sender, args ) =>
{
if(! MeetsMyExpectations( tb.Text ) )
Dispatcher.BeginInvoke(new Action(() => tb.Undo()));
};
I've read a lot of wild adventures in text box validation and this is about as easy as I have found.