我有一个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
的目标也不会更新。
答案 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