Правило проверки WPF, запрещающее десятичную запись в текстовом поле?

У меня есть текстовое поле WPF, определенное в XAML, как это:

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

Как вы можете видеть, мое текстовое поле привязано к десятичному свойству в моем бизнес-объекте с именем UpperLeftCornerLatitude, которое выглядит следующим образом:

private decimal _upperLeftCornerLongitude;
public decimal UpperLeftCornerLatitude
{
    get { return _upperLeftCornerLongitude; }
    set
    {
        if (_upperLeftCornerLongitude == value)
        {
            return;
        }

        _upperLeftCornerLongitude = value;
        OnPropertyChanged(new PropertyChangedEventArgs("UpperLeftCornerLatitude"));
    }
}

Мой пользователь будет вводить значение широты в это текстовое поле, и для проверки этой записи я создал правило проверки, которое выглядит следующим образом:

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

Мое текстовое поле изначально начинается пустым, и у меня установлена точка останова в начале моего правила проверки. Я ввожу 1 в текстовое поле, и когда мой отладчик нарушает правила валидации, я вижу это значение = "1". Все идет нормально. Теперь я продолжаю работать и ввожу десятичную точку в текстовое поле (так что теперь мы должны иметь «1»). Опять же, отладчик разрывается внутри правила проверки и, как и ожидалось, значение = «1». Если я перебираю код правила проверки, я вижу, что он проходит проверку значения широты и возвращает следующее:

new ValidationRule(true, null);

Однако, как только правило проверки возвращается и я перехожу к следующей строке кода, я оказываюсь в первой строке моего установщика свойства UpperLeftCornerLatitude. Мышление над значением показывает, что это значение «1» вместо «1». как я и ожидал. Поэтому, естественно, когда я продолжаю выполнять свой код, я снова оказываюсь в текстовом поле, начиная со значения «1» вместо «1». Если я удаляю все точки останова, то получается, что я не могу ввести десятичную точку в текстовое поле. Есть ли что-то очевидное, что я здесь упускаю, что приводит к тому, что мой сеттер получает значение «1», хотя я ввел «1». в текстовом поле? Большое спасибо!

Ответы на вопрос(6)

Ваш ответ на вопрос