加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 01:40:26 所属栏目:百科 来源:网络整理
导读:我有一个应用程序,我最近从VS 2008 .NET 3.5项目转换为VS2010 .NET 4项目.转换后,项目中的某些 WPF对话框的行为有所不同.我想了解是什么导致了这种行为上的差异,所以我可以找到并修复现在可能存在问题的其他方面. 作为一个例子,我有一个MVVM对话框,让用户输
我有一个应用程序,我最近从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>

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

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

我看过What’s New in the .NET Framework 4(包括What’s New in WPF Version 4),但我没有发现任何有关此变化的信息.

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

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

更新:删除调用RaisePropertyChanged(“ValueIsValid”);不改变行为并键入无效数字(例如“3.1a”)不会被中一次有效数字替换(例如在这种情况下为“3.1”).也可以输入数字,其精度高于3位有效数字.例如. “3.0545555” – 这个问题似乎只发生在你输入??的东西会导致第三个重要数字的四舍五入.

解决方法

这种行为差异的原因是:

In 3.5,the binding would write a new
value back to the source after each
keystroke,without changing the
TextBox text. But that text might not
represent the source’s value
accurately,perhaps because it doesn’t
include formatting and conversion,or
because the source changed the value
(in the property-setter) to something
else. This led to frequent and
vehement complaints – people wanted
the TextBox to show the source’s
value,exactly as a TextBlock would if
bound to the same property with the
same converters and formatting. The UI
should display what’s actually in the
data,not what the end-user typed.

To fix this class of bugs in 4.0,the
binding now applies formatting and
conversion to the source’s new value
after every update. (LostFocus
bindings already did this in 3.5.) The
TextBox now shows what’s in the data,
but that can make the user’s typing
more complex.

We plan to improve this scenario in
the next release in at least two ways:
1. When the TextBox text is replaced with a revised string,the insertion
point (cursor) that worked for the old
string may no longer be correct for
the new string. The heuristic that
guesses where to put the cursor can be
improved.
2. Bindings will expose a way to do LostFocus (or Explicit) updates with
partial validation after each
keystroke. The formatting/conversion
only gets applied when focus changes,
but the user gets validation feedback
after every keystroke.

  • Sam (WPF team)

从“Changed behaviour from .Net 3.5 to .Net 4.0 of WPF TextBox formatting when PropertyChanged is used as UpdateSourceTrigger”

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读