用户键入时如何进行源更新

时间:2018-12-09 04:38:10

标签: c# wpf data-binding inotifypropertychanged propertychanged

这是一个完整的菜鸟问题,我似乎无法弄清楚。我有一个文本框和一个文本块。文本框应为存款金额,文本块应为存款后的余额。基本上只是将存款箱中的值添加到新余额箱中的任何值上,但是我需要在用户输入时完成此数学运算。基本上,当用户在存款文本框中键入内容时,我希望将存款中的值添加到存款后文本块中的值。这不会更新,并且如果我通过调试器运行它,则它不会在用户键入时停止程序,因此我知道它无法识别出该属性正在更改,但是我似乎无法绕开为什么。我有datacontext设置,我知道它没有任何绑定错误,因为绑定可以使用常规文本,所以我不需要在这里显示它。我怀疑这只是我的数学和绑定简单的事情。 文本框和文本块的代码在这里:

 <!-- 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"/>

这两个属性在这里:

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

这可能是一个非常愚蠢的数学错误,但是任何帮助将不胜感激!如果您对我的代码有任何建议也可以提供帮助。谢谢!

2 个答案:

答案 0 :(得分:0)

我不确定您如何在代码中填充_balanceAfterDeposit和_balance。但是根据给出的示例代码,您仅可以在BalanceAfterDeposit中提供get。因为您已将TextBox ReadyOnly用于新的余额。因此,用户无法输入任何内容,因此,仅Get就足够了。

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

现在,为了显示更新的BalanceAfterDeposit,只要DepositAmount发生变化,即使在BalanceAfterDeposit上也需要调用PropertyChanged。因此需要在DepositAmount属性集中显式调用它。

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

已更新: 默认情况下,绑定模式为TwoWay,我已指定了OneWay绑定。这样可以解决标记运行时错误。

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

让我们为_Balance金额提供一些价值。

private double _balance=19000;

让我们更改存款后的财产余额

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

我使用了_depositAmount + _balance。

答案 1 :(得分:0)

由于您仅在DepositAmount中编辑数据,并且BalanceAfterDeposit仅是计算字段。 (我假设您正在做一些数学运算,此后,您想显示BalanceAfterDeposit。在此示例中,BalanceAfterDeposit所需的唯一输入是DepositAmount)。 现在问题在这里发生。

  1. 在DepositAmount中,您的RaiseProperty仅针对DepositAmount进行了更改。不会通知其他属性做某事。在您的情况下,您需要显式提高BalanceAfterDeposit的属性。如下所示

    公共双倍存款金额 {     得到=> this._depositAmount;     组     {         如果(this._depositAmount!=值)         {             this._depositAmount =值;             OnPropertyChanged(nameof(DepositAmount));             OnPropertyChanged(nameof(BalanceAfterDeposit));         }     } }

这将强制UI从BalanceAfterDeposit更新。因此,您将看到getter将被调用。

  1. 由于BalanceAfterDeposit是计算字段,因此您不会从外部(对于您的情况)进行更新。因此,getter对您来说足够了,即在getter中进行计算并返回。

  2. 用于改进。我想建议您定义一个异步方法,该方法基本上将进行所有计算并最终在BalanceAfterDeposit中设置值。在专用字段中设置值之后,在DepositAmount的设置器中调用此方法。 在此建议中,您必须在BalanceAfterDeposit中定义setter和getter。(如第2点中所述,您不需要setter)。