It's been a while since this was posted, but I wanted to jump in in case anyone found this answer, when faced with this question.
This solution - binding to the KeyDown event - doesn't work well.
Two problems have already been mentioned in this thread.
- The first solution messed up the carat positioning, and didn't uppercase the last letter.
- The second solution fixed the carat positioning, but still didn't uppercase the last letter.
The suggestion to use KeyUp, instead of KeyDown does result in uppercasing the last letter. But there are other problems. The way this messes about with the selection makes the content of the textbox unselectable. If you press END, then hold down the shift key, and then press HOME, you'll select the full contents of the textbox - and when you release the HOME button, everything will be unselected.
I fixed this by saving the SelectionStart and SelectionLength, in the event handler, and reapplying them after. But even with this, there's a noticeable delay - something like half-a-second - after you release the key before a lower case character is replaced by its upper.
A much better solution is to apply a CellEditTemplate to the column. Put a TextBox in the template, and set CharacterCasing="Upper" on it.