【发布时间】:2014-08-01 21:51:03
【问题描述】:
我对 WPF 比较陌生,并且遇到了数据绑定问题。我将用户控件的依赖属性绑定到后面代码中的类属性。在我的 UI 后面代码中的类实体实例化期间,通过 INotifyPropertyChanged 成功更新。但是,当随后在 OnPropertyChangedEventHandler 触发后更改我的代码中的值时,但 OnPropertyChanged 方法不再对此作出回应。详情如下。如果有人能给我一些提示我做错了什么,那就太好了。
我在后面的代码中实现了一个用户控件,该控件绑定到我的部分类的属性 CurrentAccProp.DiscountRate:
<local:doubleUEdit x:Name="InterestRate" LabelField="Interest rate" MinimumValue="0" MaximumValue="1" FormatStringForNumbers="P2" IncrementSize="0.01" UncertainValue="{Binding ElementName=RibbonWindow, Path=CurrentAccProp.DiscountRate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
CurrentAccProp 为实例的类实现 INotifyPropertyChanged 以通知 UI 值更改
//Event to inform data grid about changes
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
在 DiscountRate 属性的设置器中调用 OnPropertyChanged:
doubleU discountingrate;
public doubleU DiscountRate
{
get {return discountingrate;}
set
{
discountingrate = value;
OnPropertyChanged("DiscountingRate");
}
}
我绑定的用户控件的属性被实现为依赖属性:
//Property for data binding to doubleU
[Description("The formatstring for the double boxes"), Category("Default")]
public doubleU UncertainValue
{
get { return new doubleU(0, 0, (double)doubleUSupremum.Value, (double)doubleUSupremum.Value); }
set { doubleURangeSlider.LowerValue = value.Interval.Infimum; doubleURangeSlider.HigherValue = value.Interval.Supremum; doubleUInfimum.Value = value.Interval.Infimum; doubleUSupremum.Value = value.Interval.Supremum; }
}
public static readonly DependencyProperty UncertainValueProperty =
DependencyProperty.Register(
"UncertainValue",
typeof(doubleU),
typeof(doubleUEdit),
new PropertyMetadata(default(doubleU), OnItemsPropertyChanged));
private static void OnItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
doubleUEdit MydblUEdt = d as doubleUEdit;
MydblUEdt.UncertainValue = e.NewValue as doubleU;
}
当我在 OnPropertyChanged 后面的代码中实例化 CurrentAccProp 时,会通知 UI 并更新值。
AccountingProperties currentaccprop = new AccountingProperties(new doubleU(0.0));
public AccountingProperties CurrentAccProp { get { return currentaccprop; } set { currentaccprop = value; } }
但是,当我稍后更新 DiscountRate 的值时
CurrentAccProp.DiscountRate = new doubleU(1.0);
OnPropertyChanged 被执行,但 UI 不再更新。有谁知道我在这里做错了什么?
HighCore 和 zaknotzach 指出的错字确实是问题所在。谢谢你的帮助!我在 HighCore 引用的线程中实现了该方法以避免这种情况,它就像一个魅力。在更改后的 AccountingProperties 类下方,从中实例化 CurrentAccProp 以供参考:
public class AccountingProperties : INotifyPropertyChanged
{
doubleU discountrate;
public doubleU DiscountRate
{
get {return discountrate;}
set { SetField(ref discountrate, value, () => DiscountRate); }
}
//------------------------------------------------
//constructors
public AccountingProperties(doubleU discountrate)
{
DiscountRate = discountrate;
}
//Event to inform data grid about changes
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> selectorExpression)
{
if (selectorExpression == null)
throw new ArgumentNullException("selectorExpression");
MemberExpression body = selectorExpression.Body as MemberExpression;
if (body == null)
throw new ArgumentException("The body must be a member expression");
OnPropertyChanged(body.Member.Name);
}
protected bool SetField<T>(ref T field, T value, Expression<Func<T>> selectorExpression)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(selectorExpression);
return true;
}
}
【问题讨论】:
-
我注意到的第一件事是您的财产被称为
DiscountRate,但您正在为DiscountingRate提高财产更改。请参阅this answer 了解避免该问题的明确方法。 -
哇,谢谢。我在上面培育了两天多,你在 60 秒内就看到了。
标签: c# wpf binding inotifypropertychanged