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

本文关键字:UI 更新 绑定 对象 WPF | 更新日期: 2023-09-27 18:08:06

我对WPF比较陌生,在数据绑定方面有问题。我将用户控件的依赖项属性绑定到后面代码中的类属性。在实例化类实体的过程中,我的代码后面的UI通过INotifyPropertyChanged成功更新。然而,当随后改变我的代码背后的OnPropertyChangedEventHandler火灾的值,但OnPropertyChanged方法不再回答这个。下面是细节。如果有人能给我一些提示,我做错了什么,那就太好了。

我实现了一个用户控件,我绑定到一个属性CurrentAccProp。

后面代码中我的部分类的注释
<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));
        }
    }

OnPropertyChanged在disstate属性的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;
    }

当我实例化CurrentAccProp在我的代码后面的OnPropertyChanged通知UI和值更新。

AccountingProperties currentaccprop = new AccountingProperties(new doubleU(0.0));
public AccountingProperties CurrentAccProp { get { return currentaccprop; } set { currentaccprop = value; } }

但是,当我稍后更新discountry

的值时
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;
    }

}

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

您需要首先更改

中的字符串
OnPropertyChanged("DiscountingRate");

"DiscountRate"。你给OnPropertyChanged函数的字符串必须匹配属性名。

如前所述,问题是OnPropertyChanged("DiscountingRate");为事件提供了不正确的属性名称。

为了防止此类错误,您可以避免同时使用字符串字面值。在OnPropertyChanged参数中,使用CallerMemberName。你可以将OnPropertyChanged签名修改为

public void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
    // Do your stuff
}

然后在setter中,调用this.OnPropertyChanged();。方法将被赋予更改后的属性名。

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

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