C# WPF:绑定对象中的值更改时未更新UI

C# WPF:绑定对象中的值更改时未更新UI,c#,wpf,binding,inotifypropertychanged,C#,Wpf,Binding,Inotifypropertychanged,我对WPF比较陌生,在数据绑定方面有问题。我正在将用户控件的依赖项属性绑定到代码隐藏中的类属性。在我的代码中的类实体初始化期间,UI通过INotifyPropertyChanged成功更新。但是,当随后更改OnPropertyChangedEventHandler后面代码中的值时,OnPropertyChanged方法将触发,但OnPropertyChanged方法不再响应此问题。下面是细节。如果有人能给我一些提示我做错了什么,那就太好了 我实现了一个用户控件,该控件绑定到代码隐藏中我的分部类的

我对WPF比较陌生,在数据绑定方面有问题。我正在将用户控件的依赖项属性绑定到代码隐藏中的类属性。在我的代码中的类实体初始化期间,UI通过INotifyPropertyChanged成功更新。但是,当随后更改OnPropertyChangedEventHandler后面代码中的值时,OnPropertyChanged方法将触发,但OnPropertyChanged方法不再响应此问题。下面是细节。如果有人能给我一些提示我做错了什么,那就太好了

我实现了一个用户控件,该控件绑定到代码隐藏中我的分部类的属性CurrentAccProp.Discentrate:

<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}"/>
OnPropertyChanged在DiscountRate属性的setter中调用:

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;
    }
绑定到的用户控件的属性作为依赖项属性实现:

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;
    }
当我在代码中实例化CurrentAccProp时,OnPropertyChanged会通知UI,并更新值

AccountingProperties currentaccprop = new AccountingProperties(new doubleU(0.0));
public AccountingProperties CurrentAccProp { get { return currentaccprop; } set { currentaccprop = value; } }
但是,当我稍后更新discentrate的值时

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


}

您需要首先在中更改字符串

OnPropertyChanged("DiscountingRate");

分散注意力。为OnPropertyChanged函数指定的字符串必须与属性名称匹配。这很可能是您遇到的问题。

如前所述,问题是关于PropertyChangedDiscontingrate;为事件提供不正确的属性名称

为了防止类似这样的错误,可以避免同时使用字符串文字。在OnPropertyChanged参数中,使用。您可以将OnPropertyChanged签名修改为

public void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
    // Do your stuff
}
然后在setter中,您只需将其称为.OnPropertyChanged;。将为该方法指定已更改的属性名称

public doubleU DiscountRate 
{ 
    get {return discountingrate;} 
    set 
    {
        discountingrate = value; 
        OnPropertyChanged();
    } 
}

这样做的好处是,您可以重构代码,而不必担心破坏属性更改事件。

我注意到的第一件事是,您的属性被称为DiscountRate,但您正在为DiscountingRate而提高propertychanged。请查看避免该问题的最终方法。哇,谢谢。我在那上面繁殖了两天多,你在60秒内就看到了。捕捉得好,这实际上是可能的问题。哇,谢谢你的帮助。这就成功了。我非常专注于在代码中发现一个结构缺陷,因为当我创建属性后面的成员实例时,更新第一次起作用。但显然,当绑定元素在实例化期间将其值从null更改为有效值时,似乎有一种机制会通知UI,我还不明白这一点。