I have an app I've recently converted from a VS 2008 .NET 3.5 project, to a VS2010 .NET 4 project. Some of the WPF dialogs in the project behave differently after the conversion. I'd like to understand what is causing this difference in behaviour, so I can find and fix other areas that may now have problems.
As an example, I have a MVVM dialog that lets the user type in a number. The number is stored internally as a double, and the user can only accept the dialog if the text they type is a valid double. So I have a text box bound to a string in the ViewModel, and an OK button which is only enabled when the string is a valid double. The relevant Xaml looks like this:
<TextBox Text="{Binding ValueString, UpdateSourceTrigger=PropertyChanged}"/>
<Button IsEnabled="{Binding ValueIsValid}">OK</Button>
And the ViewModel looks like:
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;
}
This worked fine in .NET 3.5, but when it's running on .NET 4 it has a problem when the user is entering a number. For example, if the user enters "3.05555" into the text box on the .NET 3.5 version, everything is fine. However in the .NET 4 version, they can enter 3.05 fine but when they type the next "5" the value of text box changes to "3.06" and then changes to "3.07" if they press 5 again. It's as if the value is being read-back from the ValueString
property as soon as it has been set (thus being formatted as "G3"), but this didn't used to happen with .NET 3.5.
I've had a look over What's New in the .NET Framework 4 (including What's New in WPF Version 4), but I didn't find anything about this change.
If you want to see this for yourself, I've created a small example VS2010 solution you can download from here. The BindingTest2008 project has been converted from VS 2008 and targets .NET 3.5, and the BindingTest2010 project was created in VS 2010 targeting .NET 4. The code is the same in both projects, but the .NET 4 project has this problem.
I'd appreciate any help on understanding why this is happening. Thanks.
Updated: Removing the call the RaisePropertyChanged("ValueIsValid");
doesn't change the behaviour and typing an invalid number (e.g. "3.1a") doesn't intermediately get replaced by the last valid number (e.g. "3.1" in that case). Also numbers can be entered to a higher precision than 3 significant digits. E.g. "3.0545555" - the problem only seems to happen when the thing you've just typed would cause a rounding on the 3rd significant figure.