为什么绑定设置在.NET 4与.NET 3.5中的行为不同

Wil*_*lka 3 c# wpf xaml c#-4.0

我有一个应用程序,我最近从VS 2008 .NET 3.5项目转换为VS2010 .NET 4项目.转换后,项目中的某些WPF对话框的行为有所不同.我想了解是什么导致了这种行为上的差异,所以我可以找到并修复现在可能存在问题的其他方面.

作为一个例子,我有一个MVVM对话框,让用户输入一个数字.该数字在内部存储为double,如果用户输入的文本是有效的double,则用户只能接受该对话框.所以我有一个文本框绑定到ViewModel中的一个字符串,一个OK按钮仅在字符串是有效的double时启用.相关的Xaml看起来像这样:

<TextBox Text="{Binding ValueString, UpdateSourceTrigger=PropertyChanged}"/>
<Button IsEnabled="{Binding ValueIsValid}">OK</Button>
Run Code Online (Sandbox Code Playgroud)

ViewModel看起来像:

class ViewModel : INotifyPropertyChanged
{
    private double actualValue;
    public string ValueString
    {
        get { return actualValue.ToString("G3"); }
        set
        {
            double doubleValue;
            if (double.TryParse(value, NumberStyles.Float, CultureInfo.CurrentCulture, out doubleValue))
            {
                actualValue = doubleValue;
                ValueIsValid = true;
                RaisePropertyChanged("ValueString");
            }
            else
            {
                ValueIsValid = false;
            }
        }
    }

    private bool valueIsValid = true;
    public bool ValueIsValid
    {
        get { return valueIsValid; }
        set
        {
            if (valueIsValid != value)
            {
                valueIsValid = value;
                RaisePropertyChanged("ValueIsValid");
            }
        }
    }

    private void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
Run Code Online (Sandbox Code Playgroud)

这在.NET 3.5中运行良好,但是当它在.NET 4上运行时,在用户输入数字时会出现问题.例如,如果用户在.NET 3.5版本的文本框中输入"3.05555",一切都很好.但是在.NET 4版本中,它们可以输入3.05,但是当它们键入下一个"5"时,文本框的值将更改为"3.06",如果再次按5则会更改为"3.07".就好像该值ValueString一旦被设置(即格式化为"G3")就从属性中读回,但这不适用于.NET 3.5.

我已经了解了.NET Framework 4中的新功能(包括WPF第4版中的新功能),但我没有发现有关此更改的任何信息.

如果你想亲自看看这个,我已经创建了一个小例子VS2010解决方案,你可以从这里下载.BindingTest2008项目已从VS 2008转换为目标.NET 3.5,而BindingTest2010项目是在VS 2010中针对.NET 4创建的.两个项目中的代码相同,但.NET 4项目存在此问题.

我很感激任何帮助,了解为什么会这样.谢谢.

更新:删除调用RaisePropertyChanged("ValueIsValid");不会更改行为并键入无效数字(例如"3.1a")不会被中间最后一个有效数字替换(例如"3.1").也可以输入数字,其精度高于3位有效数字.例如"3.0545555" - 问题似乎只发生在您输入的东西会导致第3个有效数字的舍入时.

Wil*_*lka 5

这种行为差异的原因是:

在3.5中,绑定会在每次击键后将新值写回源,而不更改TextBox文本.但是该文本可能并不准确地表示源的值,可能是因为它不包括格式和转换,或者因为源将值(在属性设置器中)更改为其他值.这导致了频繁和激烈的抱怨 - 人们希望TextBox显示源的值,就像TextBlock绑定到具有相同转换器和格式的相同属性一样.UI应显示数据中实际存在的内容,而不是最终用户键入的内容.

要在4.0中修复此类错误,绑定现在会在每次更新后将格式化和转换应用于源的新值.(LostFocus绑定已在3.5中完成此操作.)TextBox现在显示数据中的内容,但这可能会使用户的输入更复杂.

我们计划在下一个版本中以至少两种方式改进这种情况:1.当TextBox文本被修改后的字符串替换时,用于旧字符串的插入点(游标)可能不再适用于新字符串.可以改进猜测放置光标的位置的启发式方法.2.绑定将揭示在每次击键后使用部分验证进行LostFocus(或显式)更新的方法.格式化/转换仅在焦点更改时应用,但用户在每次击键后都会获得验证反馈.

  • 山姆(WPF队)

从" 当PropertyChanged用作UpdateSourceTrigger时,从.Net 3.5到.Net 4.0的WPF TextBox格式的更改行为 "

  • 我们到了,4.5 已经出来了,行为没有改善,也没有真正的替代方案。至少可以说,编辑行为很奇怪。是时候回滚那个变化了,也许吧? (2认同)