Question

I am using .NET 4.0. I have some very simple code that lets the user type in a number between 1 and 99,999 (inclusive). I have some logic in the Property setter that prevents the latest value from being applied if it does not adhere to the business rules (e.g., it is not a number or the number is too large).

    public class MainViewModel : INotifyPropertyChanged
{
    #region Fields

    private string _text = string.Empty;

    #endregion // Fields

    #region Properties

    public string Text
    {
        get { return _text; }

        set
        {
            if (_text == value) return;

            if (IsValidRange(value))
            {
                _text = value;
            }

            OnPropertyChanged("Text");
        }
    }

    #endregion // Properties

    #region Private Methods

    private bool IsValidRange(string value)
    {
        // An empty string is considered valid.
        if (string.IsNullOrWhiteSpace(value)) return true;

        // We try to convert to an unsigned integer, since negative bill numbers are not allowed,
        // nor are decimal places.
        uint num;
        if (!uint.TryParse(value, out num)) return false;

        // The value was successfully parse, so we know it is a non-negative integer.  Now, we
        // just need to make sure it is in the range of 1 - 99999, inclusive.
        return num >= 1 && num <= 99999;
    }

    #endregion // Private Methods

    #region INotifyPropertyChanged Implementation

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion // INotifyPropertyChanged Implementation
}

The problem I am running into is that when the value is not valid and I just ignore the value, the TextBox bound to this property does not update to reflect that change; rather, it just retains the value as it is typed in. Here is how I have the property bound:

        <TextBox Grid.Row="0"
             Text="{Binding Path=Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

Can anyone tell me what I'm doing wrong?

I have read a lot of questions that seemed very similar to this, but none of the answers worked for me. The weird thing is that when I don't validate based on numbers, but just change all text typed in to be upper case, it works just fine. It just seems to not work when I try to not set the Property to the new value.

Was it helpful?

Solution

This seems to be a bug with the TextBox in .NET 3.5-4.0. I first tried this in 4.5 and your code worked as written, but when I converted the project to 4.0, I could reproduce the issue. After doing some searching, I found:

WPF Textbox refuses to update itself while binded to a view model property, which details a workaround that references:

Textbox getting out of sync with viewmodel property.

Of course if it's possible for you to use .NET 4.5 I'd suggest that, but of course it's not always as easy as that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top