【问题标题】:How to make source update while user types如何在用户键入时进行源更新
【发布时间】:2019-05-10 09:27:15
【问题描述】:

这是一个完整的菜鸟问题,我似乎无法弄清楚。我有一个文本框和一个文本块。文本框应该是存款金额,文本块应该是存款后的余额。它基本上只是将存款箱中的值添加到新余额框中的任何值中,但我需要在用户键入时完成此数学运算。基本上,当用户在存款文本框中键入时,我希望将存款中的值添加到存款后文本块中的值中。这不会更新,如果我通过调试器运行它,它不会在用户键入时停止程序,所以我知道它没有识别出属性正在被更改,但我似乎无法理解为什么.我有 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));
            }
        }
    }

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

【问题讨论】:

    标签: c# wpf data-binding inotifypropertychanged propertychanged


    【解决方案1】:

    我不确定您是如何在代码中填写 _balanceAfterDeposit 和 _balance 的。但是根据给出的示例代码,您可以在 BalanceAfterDeposit 中提供get。因为你已经为新的平衡制作了TextBoxReadyOnly。所以用户无法进入,因此只有Get就足够了。

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

    现在,为了显示更新后的 BalanceAfterDeposit,您需要调用 PropertyChanged,即使在 DepositAmount 发生变化时也是如此。所以需要在 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。

    【讨论】:

    • 文本块仍然没有更新,如果我尝试做只是在 balanceafterdeposit 上做,那么它会抛出一个 system.windows.markup.xamlparseexception
    • 是的,它修复了错误,但 UI 没有更新。如果我输入存款金额,余额保持不变。
    • 我已经在 _balance 中提供了一些金额,并使用 _depositAmount 来显示 Balance 金额的变化,因为我们不知道 _balanceAfterDeposit 是如何从示例代码中计算出来的。这将清除您的理解
    • 是的,我明白了。谢谢!!
    【解决方案2】:

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

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

      public double DepositAmount { 得到 => this._depositAmount; 放 { if (this._depositAmount != value) { this._depositAmount = 价值; OnPropertyChanged(nameof(DepositAmount)); OnPropertyChanged(nameof(BalanceAfterDeposit)); } } }

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

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

      李>
    2. 为了改进。我建议你定义一个异步方法,它基本上会做所有的计算,最后在 BalanceAfterDeposit 中设置值。在私有字段中设置值后,在 DepositAmount 的 setter 中调用此方法。 在这个建议中,您必须在 BalanceAfterDeposit 中定义 setter 和 getter。(如第 2 点中我提到您不需要 setter)。

    【讨论】:

    • 将 balanceafterdeposit 的 OnPropertyChanged 添加到 depositamount setter 后,BalanceAfterDeposit 属性仍然不会更新
    • 如果您只是添加 OnPropetyChange。它不会更新。因为它将从 BalanceAfterDeposit 获得价值。你的实现是this._balanceAfterDeposit + _balance。在您的实现中,无法将任何值设置为 _balanceAfterDeposit。因此,您需要正确设置 _balanceAfterDeposit 的值。即 public double BalanceAfterDeposit { get { return this._depositAmount + _balance; } }
    猜你喜欢
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    相关资源
    最近更新 更多