I have a WPF textbox defined in XAML like this:
<Window.Resources>
<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<TextBox x:Name="upperLeftCornerLatitudeTextBox" Style="{StaticResource textBoxInError}">
<TextBox.Text>
<Binding Path="UpperLeftCornerLatitude" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:LatitudeValidationRule ValidationStep="RawProposedValue"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
As you can see, my textbox is bound to a decimal property on my business object called UpperLeftCornerLatitude which looks like this:
private decimal _upperLeftCornerLongitude;
public decimal UpperLeftCornerLatitude
{
get { return _upperLeftCornerLongitude; }
set
{
if (_upperLeftCornerLongitude == value)
{
return;
}
_upperLeftCornerLongitude = value;
OnPropertyChanged(new PropertyChangedEventArgs("UpperLeftCornerLatitude"));
}
}
My user will be entering a latitude value into this textbox and in order to validate that entry, I've created a validation rule that looks like this:
public class LatitudeValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
decimal latitude;
if (decimal.TryParse(value.ToString(), out latitude))
{
if ((latitude < -90) || (latitude > 90))
{
return new ValidationResult(false, "Latitude values must be between -90.0 and 90.0.");
}
}
else
{
return new ValidationResult(false, "Latitude values must be between -90.0 and 90.0.");
}
return new ValidationResult(true, null);
}
}
My textbox initially starts off empty and I have a breakpoint set at the beginning of my validation rule. I enter 1 in the textbox and when my debugger breaks inside of the validation rule, I can see that value = "1". So far so good. Now I continue running and enter a decimal point in the textbox (so we should have "1." now). Again, the debugger breaks inside of the validation rule and, as expected, value = "1.". If I step through the validation rule code, I see that it passes the latitude value check and returns the following:
new ValidationRule(true, null);
However, as soon as the validation rule returns and I step into the next line of code, I find myself on the first line of my UpperLeftCornerLatitude property setter. Mousing over value here reveals that it's a value of "1" instead of "1." as I would expect. So naturally when I continue running my code, I end up back in the textbox staring at a value of "1" instead of "1.". If I remove all of the breakpoints, the effect is that I can't seem to enter a decimal point in the textbox. Is there something obvious that I'm missing here that's causing my setter to end up with a value of "1" even though I have entered "1." in the textbox? Thanks very much!
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…