Search code examples
c#wpfdata-bindinginotifypropertychangedpropertychanged

How to make source update while user types


This is a complete noob question that I am seemingly unable to figure out. I have a text box and a text block. The text box should be the deposit amount and the text block should be the balance after the deposit. It's basically just the value in the deposit box gets added to whatever value is in the new balance box, but I need this math to be done while the user types. Basically while the user types in the deposit text box I want the value in the deposit to be added to the value in the after deposit text block. This doesn't update and if I run it through the debugger it doesn't stop the program while the user types so I know it doesn't recognize that the property is being changed but I can't seem to wrap my head around why. I have the datacontext set and I know it is binded with no binding errors because the bindings work with regular text so i do not feel a need to show that here. I suspect this is just something simple with my math and the bindings. The code for the textbox and text block are here:

 <!-- TextBlock and TextBox for deposit -->
    <TextBlock Text="Deposit:" TextAlignment="Center" VerticalAlignment="Center" FontSize="30" FontWeight="Bold"/>
    <TextBox Text="{Binding DepositAmount, UpdateSourceTrigger=PropertyChanged}" BorderBrush="Black" BorderThickness="3" Padding="3" Margin="-60 15 30 10" Grid.Column="1"/>

    <!-- TextBlock and TextBox for new balance -->
    <TextBlock Text="New Balance:" Margin="5 0 0 0" TextAlignment="Left" VerticalAlignment="Center" FontSize="28" FontWeight="Bold" Grid.Row="1"/>
    <TextBox Text="{Binding BalanceAfterDeposit, UpdateSourceTrigger=PropertyChanged}" FontWeight="Bold" IsReadOnly="True" BorderBrush="Black" BorderThickness="3" Padding="3" Margin="-60 15 30 10" Grid.Column="1" Grid.Row="1"/>

The two properties are here:

public double DepositAmount
    {
        get => this._depositAmount;
        set
        {
            if (this._depositAmount != value)
            {
                this._depositAmount = value;
                OnPropertyChanged(nameof(DepositAmount));
            }
        }
    }

    public double BalanceAfterDeposit
    {
        get => this._balanceAfterDeposit + _balance;
        set
        {
            if ((this._balanceAfterDeposit + _balance) != value)
            {
                this._balanceAfterDeposit = value;
                OnPropertyChanged(nameof(BalanceAfterDeposit));
            }
        }
    }

This is probably a really dumb math mistake but any help will be appreciated! If you have any suggestions on my code that would really help too. Thanks!


Solution

  • I am not sure how you are filling the _balanceAfterDeposit and _balance in your code. But based on the sample code given you can just provide get in BalanceAfterDeposit. Because you have made the TextBox ReadyOnly for new balance. So there is no way user is able to enter and therefore, only Get is enough.

        public double BalanceAfterDeposit
        {
            get => this._balanceAfterDeposit + _balance;
        }
    

    Now, in order to show the updated BalanceAfterDeposit you need to call the PropertyChanged even on BalanceAfterDeposit whenever there is change in DepositAmount. So need to call it explicitly in set of DepositAmount Property.

            public double DepositAmount
        {
            get => this._depositAmount;
            set
            {
                if (this._depositAmount != value)
                {
                    this._depositAmount = value;
                    OnPropertyChanged(nameof(DepositAmount));
                    OnPropertyChanged(nameof(BalanceAfterDeposit));
                }
            }
        }
    

    Updated: By default Binding Mode is TwoWay, I have given OneWay Binding. This will resolve the markup runtime error.

     <TextBox Text="{Binding BalanceAfterDeposit, UpdateSourceTrigger=PropertyChanged,Mode=OneWay}" FontWeight="Bold" IsReadOnly="True" BorderBrush="Black" BorderThickness="3" Padding="3" Margin="68,15,30,10" Grid.Column="1" Grid.Row="1"/>
    

    Let's give some value for _Balance amount.

    private double _balance=19000;
    

    and let's change the property Balance after Deposit

            public double BalanceAfterDeposit
        {
            get => this._depositAmount + _balance;
        }
    

    I used _depositAmount + _balance.