Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding how PropertyChanged mechanism works (workflow)

Tags:

c#

events

Clarifications: 1.- I don't know if this has an specific name or word to reference it in English or programming slang, so maybe this can be a duplicate post, since I'm can't look about it.

2.- I'm totally newbie with this stuff, I've never used handlers, so that's part of the problem.

I'm trying to understand how the NotifyPropertyChanged mechanism works. Based on: INotifyPropertyChanged, focusing on the example. (I'm looking it in Spanish, above you can change it to the original English one if it doesn't change auto.

Now I'm going to extract the main code that makes me wonder, and try to analyze it. Hope you can show me where (if exist) i'm wrong and what I can't understand. Let's focus on the class that implements the interface.

// This is a simple customer class that 
// implements the IPropertyChange interface.
public class DemoCustomer : INotifyPropertyChanged
{
    // These fields hold the values for the public properties.
    private Guid idValue = Guid.NewGuid();
    private string customerNameValue = String.Empty;
    private string phoneNumberValue = String.Empty;

    public event PropertyChangedEventHandler PropertyChanged;

    // This method is called by the Set accessor of each property.
    // The CallerMemberName attribute that is applied to the optional propertyName
    // parameter causes the property name of the caller to be substituted as an argument.
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    // The constructor is private to enforce the factory pattern.
    private DemoCustomer()
    {
        customerNameValue = "Customer";
        phoneNumberValue = "(312)555-0100";
    }

    // This is the public factory method.
    public static DemoCustomer CreateNewCustomer()
    {
        return new DemoCustomer();
    }

    // This property represents an ID, suitable
    // for use as a primary key in a database.
    public Guid ID
    {
        get
        {
            return this.idValue;
        }
    }

    public string CustomerName
    {
        get
        {
            return this.customerNameValue;
        }

        set
        {
            if (value != this.customerNameValue)
            {
                this.customerNameValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public string PhoneNumber
    {
        get
        {
            return this.phoneNumberValue;
        }

        set
        {
            if (value != this.phoneNumberValue)
            {
                this.phoneNumberValue = value;
                NotifyPropertyChanged();
            }
        }
    }

Well, what do I understand? (or believe it).

From:

public event PropertyChangedEventHandler PropertyChanged;

1.- PropertyChanged is a method. The one which would be executed when ProperyChanged event triggers.

Doubt: But this method is never implemented...

From:

private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

2.- NotifyPropertyChanged is a method. Created by us, can have any name we desire. This method will be launched by us when a property gets modified.

Question: Does this method triggers ProperyChanged event?

Doubt: For me, as I can see there, no one launches this event, but the method we've created to be launch when triggers. But since it doesn't triggers, and instead of it we directly launch the method...

Mixture final think: NotifyPropertyChanged throws the event using the Hanlder, in order to be caught by the "superior entity" (the binding source in the example code), which receives the modified property in order to can update it. Then, if I want to know which elements/classes can be aware of this kind of events, what can I do?

I think this last one is the correct one, but since I'm not and expert but my thinking while trying to understand it and writing this question, I'd like you to correct me.

Thanks so much!

UPDATED

Thanks so much to all! Then, Can I suscribe to the event with the method i want? I've tried:

objetos[usados] = new ItemDB();
objetos[usados].PropertyChanged += mensaje();

With:

public async void mensaje(string cadena)
{
    var dlg = new ContentDialog(){
        Title = "My App",
        Content = cadena,
        PrimaryButtonText = "Yes",
        SecondaryButtonText = "No"
    };

    var result = await dlg.ShowAsync();

}

But then VS says:

Error 1 Ninguna sobrecarga correspondiente a 'mensaje' coincide con el 'System.ComponentModel.PropertyChangedEventHandler' delegado

Translated:

Error 1 No one overload corresponding to 'mensaje' matches with 'System.ComponentModel.PropertyChangedEventHandler' delegate

Why doesn't it work, since my event is given with an arg that is a string, and mensaje receives as an argument and string?

like image 846
Btc Sources Avatar asked Jan 20 '15 10:01

Btc Sources


2 Answers

I recommend you look up Events and Delegates in C# for further reading.

public event PropertyChangedEventHandler PropertyChanged;

PropertyChanged ist an EventHandler, which is a delegate. Other code can register here and get executed when the delegate is called.

So what happens with INotifyPropertyChanged is:

Some Code (propably the binding in Xaml) registers for the PropertyChanged event:

yourobject.PropertyChanged += MethodThatShouldBeCalledWhenThePropertyChanges;

(This is most properly auto generated somewhere, because it happens from xaml, but you could as well to it this way by hand.)

In the NotifyPropertyChanged Method, the event delegate gets executed. It simply executes all methods that were added to the event.

So to answer your questions:

Yes, the code in NotifyPropertyChanged "triggers" the event. It calls every method that was added to the event.

Any code can register for events.

As of your Update:

I again recommend reading into delegates.

You can think of delegates as Method Interface. It defines that a method has to take specific parameter types to match the delegate.

PropertyChanged is of type PropertyChangedEventHandler which takes an object and a PropertyChangedEventArgs parameter.

So any method like this is suitable:

void MethodName(
Object sender,
PropertyChangedEventArgs e
)
like image 147
Kai Brummund Avatar answered Sep 20 '22 13:09

Kai Brummund


First, you are correct, NotifyPropertyChanged is a user-defined function. It is indented just to avoid doubling of logic as soon as more properties are used. Second, NotifyPropertyChanged will not be executed when the event triggers, but the other way round; as soon as NotifyPropertyChanged is called, the event is triggered. If a suitable control is bound, it will, so to speak, consume the event and probably update itself. The event can be seen as an outlet on which other code can register callbacks. Furthermore, the Attribute CallerMemberName was introduced with .NET 4.5. The same result can be achieved without using it, but for each call of NotifyPropertyChanged the name of the property would have to be given explicitly.

like image 44
Codor Avatar answered Sep 21 '22 13:09

Codor