I’m building a WPF application using Visual Studio 2019. One of the views of this application has a TextBox
inside of it, which is binded to a property of its DataContext
. The code related to the TextBox
is this:
<TextBox x:Name="Alpha" Text="{Binding Model.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True, Converter={StaticResource ToUpper}}" />
As you can guess, the ToUpper
converter makes the text inside the TextBox
uppercase. When I write something inside the TextBox
, I see it’s uppercase, so the converter seems to work. So far so good, but the problem is that the last character seems to be “missing” during the conversion. I say that because when I write something in the TextBox
, text that is made uppercase by the converter, in the code-behind of the view:
private void OnLoaded(object sender, RoutedEventArgs e)
Alpha.KeyDown += Alpha_KeyDown;
}
private void Alpha_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) {
if (e.Key == Key.Return) {
var a = Alpha.text;
}
}
I find that the a
variable stores the exact same text of the TextBox
, but with the last character lowercase. For example, if I write “abcde” inside the TextBox
, the converter makes it uppercase and the view renders “ABCDE”, but a
is set to “ABCDe”.
The Convert()
method of the converter is this:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
var myString = value as string;
return text != null ? text.ToUpper() : "No text";
}
Why does this happen?
The KeyDown event is triggered before the Text property changes. The following can make it clear:
private void Alpha_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
Debug.WriteLine("After return: " + Alpha.Text);
}
else
{
Debug.WriteLine(Alpha.Text + e.Key.ToString().ToUpper());
}
}
So, by this time Alpha.Text haven't updated with the new key and hence not converted.