简体   繁体   中英

INotifyPropertyChanged not firing PropertyChanged

I have searched the forums for a solution but none of the listed solutions have helped. I'm assuming my implementation is off but I don't understand what or why.

Using Xamarin forms I am trying to get a label to update when an object's data is changed.

Relevant Code:

public new event PropertyChangedEventHandler PropertyChanged;

protected new virtual void OnPropertyChanged(string propertyName)
{
    System.Diagnostics.Debug.WriteLine ("Before");
    if (PropertyChanged != null)
    {
        System.Diagnostics.Debug.WriteLine ("Fired");
        PropertyChanged(this,
            new PropertyChangedEventArgs(propertyName));
    }
}

public string String {
    set { 
        if (_data == value)
            return;
        _data = value;
    OnPropertyChanged ( "String" ); }

    get { return _data; }
}

public new View Content {
        get { 
            label = new Label { Text = String };
            label.SetBinding( Label.TextProperty, new Binding( "String" ) );
            return label;}
    }

Basically, "Before" is printed to the console, but "Fired" does not get printed. This means PropertyChanged is null, so PropertyChanged is not being firing.

What am I missing?

I don't know if this is affecting it or not (probably not), but I would rewrite your property changed method to the following.

protected new virtual void OnPropertyChanged(string propertyName)
{
    System.Diagnostics.Debug.WriteLine ("Before");
    var handler = this.PropertyChanged;
    if (handler == null)
    {
        return;
    }

    System.Diagnostics.Debug.WriteLine ("Fired");
    handler(this,
        new PropertyChangedEventArgs(propertyName));
}

Grabbing a local reference to the event will protect you in a multi-threaded environment. It's a best practices thing, even if you don't write multi-threaded code. It's a safer approach when dealing with events.

See this answer on Stackoverflow regarding it.

The assignment to a local variable ensures that if the event gets unregistered between the if and the actual invocation, the invocation list will not be null (since the variable will have a copy of the original invocation list).

This can easily happen in multithreaded code, where between checking for a null and firing the event it may be unregistered by another thread.

Next, I would rename the property from String to something else. I believe Xamarin's implementation of the .NET framework includes the BCL type String. You could be confusing the binding engine, although it should be smart enough to recognize the difference.

Also, make sure that the Binding member has its direction set to Two-Way and it's update change notification set to PropertyChanged . This will ensure that the OnPropertyChanged method is always fired when the property value is changed.

new Binding("String")
{
    Mode = BindingMode.TwoWay,
    UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM