Я бы использовал PreviewTextInput, большинство событий в WPF имеют одноуровневый элемент Preview. Если вы установите e.Handled = true, это остановит событие от bubbelig / туннелирования в дальнейшем.
Я не уверен, что вы знаете об этом, но события предварительного просмотра, как говорят, туннелируют, т.е. они начинаются с самого внешнего контейнера и размещаются в каждом контейнере, пока не достигнут элемента управления, на котором находится фокус. События без предварительного просмотра называются всплывающими, т.е. они начинаются с элемента управления с фокусом и отправляются каждому родительскому элементу управления.
Если вы установите e.Handled = true в событии PreviewTextChanged внешней сетки, вы также отмените все другие события, включая TextChanged. Сначала все события предварительного просмотра запускаются из самого внешнего элемента управления с фокусом, затем все события без предварительного просмотра запускаются из элемента управления с фокусом и в самый внешний родительский элемент управления.