为什么我的WPF转换器“缺少”文本框中的最后一个字符?

问题描述

我正在使用Visual Studio 2019构建WPF应用程序。此应用程序的其中一个视图内部有一个DataContext,该视图绑定到其TextBox属性。与<TextBox x:Name="Alpha" Text="{Binding Model.Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True,Converter={StaticResource toupper}}" /> 相关的代码是这样的:

toupper

您可能会猜到,TextBox转换器使文本在TextBox内大写。当我在TextBox中写东西时,我看到它是大写的,因此转换器似乎可以工作。到目前为止,还不错,但是问题是转换过程中最后一个字符似乎“丢失”了。我之所以这样说是因为,当我在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; } } 中编写内容时,在视图的代码背后,转换器将其转换为大写的文本:

a

我发现TextBox变量存储与TextBox完全相同的文本,但最后一个字符小写。例如,如果我在a内写“ abcde”,则转换器将其变为大写,并且视图呈现“ ABCDE”,但是Convert()设置为“ ABCDe”。

转换器的public object Convert(object value,Type targettype,object parameter,CultureInfo culture) { var myString = value as string; return text != null ? text.toupper() : "No text"; } 方法是这样的:

var containerBuilder = new ContainerBuilder();

containerBuilder.RegisterType<ImplA>().As<IMyInterface>().InstancePerMatchingLifetimeScope(MyScope.A);
containerBuilder.RegisterType<ImplB>().As<IMyInterface>().InstancePerMatchingLifetimeScope(MyScope.B);

IContainer container = containerBuilder.Build();
using (ILifetimeScope lifetimeScope = container.BeginLifetimeScope(MyScope.A))
{
    IMyInterface c = lifetimeScope.Resolve<IMyInterface>();
    Console.WriteLine(c.GetType());
}

using (ILifetimeScope lifetimeScope = container.BeginLifetimeScope(MyScope.B))
{
    var c = lifetimeScope.Resolve<IMyInterface>();
    Console.WriteLine(c.GetType());
}

为什么会这样?

解决方法

您的转换器通过文本框文本和viewmodel属性之间的绑定机制在传输时更改值。

要清楚

它不会更改键入的值。

您正在使用keydown事件直接从文本框中获取数据:

private void FiscalCodeEb_KeyDown(object sender,System.Windows.Input.KeyEventArgs e) 
 {
   if (e.Key == Key.Return) {
       var a = Alpha.text;
    }
}

那没有被转换。

请改用您的viewmodel属性中的值。

,

在Text属性更改之前触发KeyDown事件。以下内容可以使您清楚:

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());
 }
}

因此,这一次Alpha.Text尚未使用新密钥进行更新,因此未进行转换。