Jane wang
Jane wang

Reputation: 308

One of two text boxes are not updated with binding

I have two search text boxes, Above and Below, that I have to set restrains on. The number in Below can't be higher than the number in Above and the number in Above can't be lower than the one in Below.

If one number is not right, it will should be set equal to the other number.

The problem is that Above doesn't get updated, while Bottom does (even though the properties are set in the same way).

xaml:

<common:SearchTextBox Grid.Column="1" 
    VerticalAlignment="Center"
    Label="Enter value in feet"
    common:AllowableTextInput.IsIgnoreWhiteSpace="True"
    common:AllowableTextInput.IsMatch="^[0-9]{0,5}$"
    Text="{Binding Path=AboveAircraft, UpdateSourceTrigger=PropertyChanged,
      Converter={StaticResource AboveAircraftConveter}, ConverterParameter=4000}"/>
<Label Grid.Row="1" Grid.Column="0" 
    Style="{StaticResource FormLabelStyle}"
    Content="Below Aircraft (ft):"/>
<common:SearchTextBox Grid.Row="1" Grid.Column="1" 
    VerticalAlignment="Center" HorizontalAlignment="Stretch"
    common:AllowableTextInput.IsIgnoreWhiteSpace="True"
    common:AllowableTextInput.IsMatch="^[0-9]{0,5}$"
    Text="{Binding Path=BelowAircraft, UpdateSourceTrigger=PropertyChanged,
      Converter={StaticResource BelowAircraftConveter}, ConverterParameter=2000}"
    Label="Enter value in feet" />

C#:

public int AboveAircraft
{
    get { return _above; }
    set
    {   
        if (SetProperty(ref _above, value, "AboveAircraft") && _updateModel)
        {
            if (Model.AltitudeBand == null)
            {
                Model.AltitudeBand = new AltitudeBand();
            }

            if (PropertyChanged != null)
            {

                PropertyChanged(this, new PropertyChangedEventArgs("AboveAircraft"));
                if (_above < _below)
                {
                     _below = AboveAircraft;
                }
            }

            Model.AltitudeBand.Above = new AltitudeBandLimit() { Unit = AltitudeUnit.Foot, Value = _above };
        }
    }
}

/// <summary>
/// Below the route of flight in ft
/// </summary>
public int BelowAircraft
{
    get { return _below; }
    set
    {
       if (SetProperty(ref _below, value, "BelowAircraft") && _updateModel)
       {
            if (Model.AltitudeBand == null)
            {
                Model.AltitudeBand = new AltitudeBand();
            }

            if (PropertyChanged != null)
            {
                _below = value;
                PropertyChanged(this, new PropertyChangedEventArgs("BelowAircraft"));
                if (_below > _above)
                {
                    AboveAircraft = _below;
                }
            }
           Model.AltitudeBand.Below = new AltitudeBandLimit() { Unit = AltitudeUnit.Foot, Value = _below };
        }
    }
}

Upvotes: 1

Views: 110

Answers (1)

Tseng
Tseng

Reputation: 64121

You are using _below = AboveAircraft; in your AboveAircraft setter method but you are binding BelowAircraft.

Either change _below = AboveAircraft; to BelowAircraft = AboveAircraft; or send notification for BelowAircraft too, i.e.

            if (PropertyChanged != null)
            {

                PropertyChanged(this, new PropertyChangedEventArgs("AboveAircraft"));
                if (_above < _below)
                {
                     _below = AboveAircraft;
                     PropertyChanged(this, new PropertyChangedEventArgs("BelowAircraft"));
                }
            }

When you change a property that changes another binded property, you have to send notification for both Properties, not only one.

Of course you have to apply the same changes to the BelowAircraft setter too.

Edit: Just for clarification: Which one of the both methods depends if setting the property would cause a circular event triggering or not. If it would cause a circular event (i.e. endless triggering) then you only have to send a second notification like the code above.

Edit 2: In reply to the comment, your XAML Binding is set to UpdateSourceTrigger=PropertyChanged. This means, your setter will be called with each character you type in.

When you enter "4000" the first character in the "Above" field will be 4 and this causes the below value to 4. Instead you want to update the Text field only when the user has completed his input.

According to the MSDN documentation for "UpdateSourceTrigger Enumeration" there are 4 values. For text field you may want to use UpdateSourceTrigger=Default or UpdateSourceTrigger=LostFocus. Then the setter will only be called when the user is finished with his input instead of calling the setter on each character typed in the text field.

Upvotes: 3

Related Questions