Para responder al enfoque de simbay, que creo que se descarta.
No puede llamar a Deshacer en TextChanged porque la operación de deshacer todavía está siendo preparada por el TextBox. Parece funcionar a veces y no en otras ocasiones, por lo que esto sugiere que hay una condición de carrera entre cuando se señala el evento y la finalización de la preparación de deshacer.
Sin embargo, al invocar Deshacer invocado en el Dispatcher, el cuadro de texto completará su preparación para deshacer. Puede validar los resultados del cambio de texto y luego decidir si desea mantener o deshacer el cambio. Puede que este no sea el mejor enfoque, pero lo intenté y destruí un montón de cambios de texto y pegué en el cuadro de texto y no pude reproducir la excepción.
La "respuesta aceptada" es excelente SÓLO si desea evitar que se ingrese o pegue un carácter no válido, pero en general a menudo valgo mucho más la validación de la entrada de TextBox y quiero verificar el valor del texto final. No es fácil discernir el texto final de un evento de vista previa porque, en lo que respecta al control, nada ha sucedido todavía.
Para responder a la pregunta de Terribad, la respuesta de Simbay es mejor y más concisa en más situaciones.
tb.TextChanged =+ (sender, args) =>
{
if(! MeetsMyExpectations(tb.Text))
Dispatcher.BeginInvoke(new Action(() => tb.Undo()));
}
He leído un montón de aventuras salvajes en la validación de cuadro de texto y esto es casi tan fácil como lo he encontrado.
Debería usar comportamientos en su lugar. – SepehrM
SepehrM: ¿podría dar un ejemplo? ¿Qué sucede si aún NO quiere validar, pero solo quiere evitar que este maldito mensaje de excepción arruine su sesión? Estoy obteniendo esto cuando un usuario escribe un poquito demasiado rápido o tal vez pega una porción de datos en el campo. Ni siquiera validando. – Allen