简体   繁体   English

DataBinding具有只读属性

[英]DataBinding with read-only property

I have a view that allows the user to enter a payment amount, then optionally enter principal, interest, and escrow amounts. 我有一个允许用户输入付款金额的视图,然后可选择输入本金,利息和托管金额。

Everything is good with those four TextBox es using TwoWay databinding like so: 使用TwoWay数据绑定的四个TextBox就像这样一切都很好:

<TextBlock Grid.Row="3"
           Grid.Column="0"
           Text="Payment Amount" />
<TextBox Grid.Row="3"
         Grid.Column="1"
         Text="{x:Bind ViewModel.CurrentPayment.PaymentAmount, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:N}', Mode=TwoWay}" />
<TextBlock Grid.Row="4"
           Grid.Column="0"
           Text="Principal" />
<TextBox Grid.Row="4"
         Grid.Column="1"
         Width="100" Text="{x:Bind ViewModel.CurrentPayment.PrincipalAmount, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:N}', Mode=TwoWay}" />
<TextBlock Grid.Row="5"
           Grid.Column="0"
           Text="Interest" />
<TextBox Grid.Row="5"
         Grid.Column="1"
         Width="100"
         MaxLength="20"
         Text="{x:Bind ViewModel.CurrentPayment.InterestAmount, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:N}', Mode=TwoWay}" />
<TextBlock Grid.Row="6"
           Grid.Column="0"
           Text="Escrow" />
<TextBox Grid.Row="6"
         Grid.Column="1"
         Width="100"
         MaxLength="20"
         Text="{x:Bind ViewModel.CurrentPayment.EscrowAmount, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:N}', Mode=TwoWay}" />

However, when I try to add a "summary" property called TotalAmount that takes the total of PrincipalAmount + InterestAmount + EscrowAmount as shown here: 但是,当我尝试添加一个名为TotalAmount的“summary”属性时,它接受PrincipalAmount + InterestAmount + EscrowAmount ,如下所示:

[JsonIgnore]
public decimal TotalAmount
{
    get
    {
        var amount = EscrowAmount + InterestAmount + PrincipalAmount;
        return amount;
    }
}

My property does not update if the user makes changes to the TextBox for principal/interest/escrow amounts. 如果用户对TextBox的主要/利息/托管金额进行了更改,则我的属性不会更新。 The TotalAmount displays correctly when loading the view, but does not update when the values change. 加载视图时, TotalAmount会正确显示,但值会更改时不会更新。 Here is the XAML for the TextBlock : 这是TextBlock的XAML:

<TextBlock Text="{x:Bind ViewModel.CurrentPayment.TotalAmount, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:N}'}" />

Is there a way to let the TotalAmount property know when one of the other properties' value changes, so it can update the displayed value? 有没有办法让TotalAmount属性知道其他属性之一的值何时发生变化,以便更新显示的值?

EDIT 编辑

Adding the other three property definitions to show use of INotifyPropertyChanged . 添加其他三个属性定义以显示INotifyPropertyChanged使用。

private decimal _principalAmount;
[JsonProperty("principalamount")]
public decimal PrincipalAmount
{
    get { return _principalAmount; }
    set { Set(ref _principalAmount, value); }
}

private decimal _escrowAmount;
[JsonProperty("escrowamount")]
public decimal EscrowAmount
{
    get { return _escrowAmount; }
    set { Set(ref _escrowAmount, value); }
}

private decimal _interestAmount;
[JsonProperty("interestamount")]
public decimal InterestAmount
{
    get { return _interestAmount; }
    set { Set(ref _interestAmount, value); }
}

Set is a method from Template 10's BindableBase : Set是Template 10的BindableBase一个方法:

public abstract class BindableBase : IBindable, INotifyPropertyChanged
{
    protected BindableBase();

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null);
    public virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression);
    public virtual bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null);
    public virtual bool Set<T>(Expression<Func<T>> propertyExpression, ref T field, T newValue);
}

EDIT 编辑

The main issue I was having was due to the different behavior of compiled bindings. 我遇到的主要问题是由于编译绑定的不同行为。 The default Mode is OneTime , which is different from the standard binding default of OneWay . 默认ModeOneTime ,与OneWay的标准绑定默认值不同。 Once I raised the property change notifications to the TotalValue property, I still had to change the binding mode to OneWay to get my UI to update. 一旦我将属性更改通知提交到TotalValue属性,我仍然必须将绑定模式更改为OneWay以使我的UI更新。

More information about standard bindings and compiled bindings can be found at x:Bind markup extension 有关标准绑定和编译绑定的更多信息,请参见x:Bind标记扩展

Yes, your model class (Payment) should implement INotifyPropertyChanged and raise PropertyChanged event for property TotalAmount when one of those three properties change. 是的,当这三个属性中的一个发生更改时,您的模型类(Payment)应实现INotifyPropertyChanged并为属性TotalAmount引发PropertyChanged事件。

And make sure that you raise PropertyChanged for TotalAmount after you set the new value, otherwise it will not update the TotalAmount with the latest values, which is probably not what you want. 并确保在设置新值后为TotalAmount引发PropertyChanged ,否则它将不会使用最新值更新TotalAmount ,这可能不是您想要的。

Example: 例:

Payment : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private decimal _principalAmount;
    public decimal PrincipalAmount
    {
        get { return _principalAmount; }
        set
        {
            _principalAmount = value;
            NotifyPropertyChanged(nameof(PrincipalAmount));

            // lets the design know that property "TotalAmount" should also be updated ...
            NotifyPropertyChanged(nameof(TotalAmount));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM