wpf绑定中的源更新

时间:2013-08-20 08:21:56

标签: c# wpf xaml data-binding

我有一个WPF窗口并为其提供一个DataContext,当目标更改它时(通过使用UpdateSourceTrigger),但当其中一个DataContext属性(源)发生更改时,目标不会更新。有没有办法在源更新时强制进行目标绑定更新?对于一个项目,是否有类似ObservableCollection的内容?

这是我的班级:

public class PaymentDetailInfo : INotifyPropertyChanged
{
    public Payment Payment
    {
        get;
        set;
    }

    public int SumOfValidNormalOverTimePrice
    {
        get
        {
            return 100 * Payment.ConsideredValidNormalOverTime / 60;
        }
    }
    public int SumOfInvalidNormalOverTimePrice
    {
        get
        {
            return 100 * Payment.ConsideredInvalidNormalOverTime / 60;
        }
    }
    public int SumOfOverPriceConst
    {
        get
        {
            int _sumOfOverPriceConst = 0;

            if (!Payment.ValidNormalOverTimePriceIsPercent)
                _sumOfOverPriceConst += SumOfValidNormalOverTimePrice;

            if (!Payment.InvalidNormalOverTimePriceIsPercent)
                _sumOfOverPriceConst += SumOfInvalidNormalOverTimePrice;

            _sumOfOverPriceConst += Payment.RewardPrice;

            return _sumOfOverPriceConst;
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, e);
    }

}

我的窗口中的某些元素绑定到Payment PaymentDetailInfo(付款是数据库表),因此示例用户可以更改Payment.ConsideredValidNormalOverTime,然后PaymentDetailInfo.SumOfValidNormalOverTimePrice将更改然后PaymentDetailInfo.SumOfOverPriceConst会改变。但是,即使我的表单的datacontext已更新,绑定到PaymentDetailInfo.SumOfOverPriceConst的目标也不会更新。

1 个答案:

答案 0 :(得分:2)

更新2:*

现在付款会在构建时传递给 PaymentDetailInfo PaymentDetailInfo 包含付款的属性,因此您可以单独在 PaymentDetailInfo 上创建绑定。

我已将 SumOfValidNormalOverTimePrice 的设置者设为私有。我认为这应该有用但我还没有测试过它。

public class PaymentDetailInfo : INotifyPropertyChanged
{

/// <summary> The payment model.
/// </summary>
private Payment _model = null;

/// <summary> Constructor.
/// </summary>
public PaymentDetailInfo(Payment payment)
{
    _model = payment;
}

/// <summary> Wrapper around Payment.ConsideredValidNormalOverTime.
/// </summary>
public int ConsideredValidNormalOverTime
{
    get { return _model.ConsideredValidNormalOverTime; }
    set
    {
        _model.ConsideredValidNormalOverTime = value;

        // make sure to set the property and not the backing field, otherwise OnPropertyChanged won't be 
        // called and the value of _sumOfValidNormalOverTimePrice will be incorrect
        SumOfValidNormalOverTimePrice = value;

        OnPropertyChanged(new PropertyChangedEventArgs("ConsideredValidNormalOverTime"));
    }
}

private int _sumOfValidNormalOverTimePrice = 0;
public int SumOfValidNormalOverTimePrice
{
    get { return _sumOfValidNormalOverTimePrice; }
    private set
    {
        _sumOfValidNormalOverTimePrice = 100 * value / 60;
        OnPropertyChanged(new PropertyChangedEventArgs("SumOfValidNormalOverTimePrice"));
    }
}

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(PropertyChangedEventArgs e)
{
    if (PropertyChanged != null)
        PropertyChanged(this, e);
}
}

<强>更新

由于付款的更改应触发更新,因此我会撤消付款 PaymentDetailInfo 之间的关联。然后在 payment.DetailInfo

上进行绑定
public class Payment
{
    public PaymentDetailInfo DetailInfo = new PaymentDetailInfo();

    private int _consideredValidNormalOverTime = 0;
    public int ConsideredValidNormalOverTime
    {
        get
        {
            _return _consideredValidNormalOverTime;
        }
        set
        {
            _consideredValidNormalOverTime = value;
            DetailInfo.SumOfValidNormalOverTimePrice = _consideredValidNormalOverTime;
        }
    }
}

public class PaymentDetailInfo : INotifyPropertyChanged
{    
    private int _sumOfValidNormalOverTimePrice = 0;
    public int SumOfValidNormalOverTimePrice
    {
        get
        {
            return __sumOfValidNormalOverTimePrice;            
        }
        set
        {
            __sumOfValidNormalOverTimePrice = 100 * value / 60;
            OnPropertyChanged(new PropertyChangedEventArgs("SumOfValidNormalOverTimePrice"));
        }
    }    

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, e);
    }
}

现在,当 ConsideredValidNormalOverTime 更新时, SumOfValidNormalOverTimePrice 也会自动更新源。为所有剩余的属性实现它,它应该工作。试想一下将 SumOfOverPriceConst 的逻辑放在哪里。由于它很大程度上依赖于付款,你可能应该把它放在那里。

<强>原始

以下是实施 INotifyPropertyChanged 的示例。只要名称更改,目标就会更新。

public class Foo: INotifyPropertyChanged
{
    #region field and properties

    private string _name = String.Empty;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged(new PropertyChangedEventArgs("Name"));
        }
    }


    #endregion

    #region INotifyPropertyChanged implementation

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, e);
    }

    #endregion