DataBinding具有只读属性

时间:2017-02-20 22:51:50

标签: c# xaml data-binding uwp

我有一个视图,允许用户输入付款金额,然后可选择输入本金,利息和托管金额。

对于使用TextBox数据绑定的四个TwoWay es,一切都很好:

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

但是,当我尝试添加一个名为TotalAmount的“摘要”属性时,会占用PrincipalAmount + InterestAmount + EscrowAmount的总和,如下所示:

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

如果用户对主体/利息/托管金额的TextBox进行了更改,则我的属性不会更新。加载视图时TotalAmount正确显示,但值更改时不会更新。以下是TextBlock

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

有没有办法让TotalAmount属性知道其他属性的某个值何时发生变化,以便更新显示的值?

修改

添加其他三个属性定义以显示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是模板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);
}

修改

我遇到的主要问题是由于编译绑定的不同行为。默认ModeOneTime,与标准绑定默认值OneWay不同。一旦我将属性更改通知提交到TotalValue属性,我仍然需要将绑定模式更改为OneWay以使我的UI更新。

有关标准绑定和编译绑定的更多信息,请访问x:Bind markup extension

1 个答案:

答案 0 :(得分:1)

是的,当这三个属性中的一个发生更改时,您的模型类(付款)应实施INotifyPropertyChanged并为属性PropertyChanged举起TotalAmount事件。

确保在设置新值后为PropertyChanged引发TotalAmount,否则它不会使用最新值更新TotalAmount,这可能不是您想要的

示例:

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