Joe Slater
Joe Slater

Reputation: 2473

INotifyPropertyChanged when exposing raw Model instead of individual properties

Here is the way I am implementing INotifyPropertyChanged at the moment-

public class ViewModel : INotifyPropertyChanged
{
    public Person Person1 { get; set; }
    public Person Person2 { get; set; }

    public string Person1Name
    {
        get { return Person1.Name; }
        set 
        { 
            Person1.Name = value;
            RaisePropertyChangedEvent("Person1Name");
        }
    }

    public string Person2Name
    {
        get { return Person2.Name; }
        set 
        { 
            Person2.Name=value;
            RaisePropertyChangedEvent("Person2Name");
        }
    }
}

//This is the Model
public class Person
{
    private string _name;
    public string Name { get; set; }
}

And the XAML I am using for this type of implementation -

<Label Text="{Binding Path=Person1Name}"/>
<Label Text="{Binding Path=Person2Name}"/>

What I want to do is to IRaisePropertyChangedEvent whenever any property within the model changes, but I do not want to explicitly expose the property as I am doing there. I simply want to expose the whole model, and whenever a property within the model changes, it should raise notify event. But I do not want the model to implement INotifyPropertyChanged, I want ViewModel to implement it. So basically what I am looking is something like this -

public class ViewModel : INotifyPropertyChanged
{
    public Person Person1
    {
        get { return _person1; }
        set
        {
            _person1 = value;
            RaisePropertyChangedEvent("Person1"); 
            //So, whenever a property within my Person1 changes, raise event for that property.
        }
    }
    public Person Person2
    {
        get { return _person2; }
        set
        {
            _person2 = value;
            RaisePropertyChangedEvent("Person2");
        }
    }
}

XAML:

<Label Text="{Binding Path=Person1.Name}"/>
<Label Text="{Binding Path=Person2.Name}"/>

How would I do this? If think question is unclear, please comment and I will try better.

Upvotes: 2

Views: 92

Answers (2)

Maciej
Maciej

Reputation: 2185

You should wrap your Person object in a ViewModel also:

public class PersonViewModel : INotifyPropertyChanged
{
   private Person _person;

   public PersonViewModel(Person person)
   {
       _person = person;
   }

   public string Name
   {
       get 
       {
           return _person.Name;
       }
       set
       {
          _person.Name = value;
          RaiseNotifyPropertyChanged("Name");
       }
    }
}

then your viewmodel class will look like:

public class ViewModel : INotifyPropertyChanged
{
    public PersonViewModel Person1
    {
        get { return _person1; }
        set
        {
            _person1 = value;
            RaisePropertyChangedEvent("Person1"); 
            //So, whenever a property within my Person1 changes, raise event for that property.
        }
    }
    public PersonViewModel Person2
    {
        get { return _person2; }
        set
        {
            _person2 = value;
            RaisePropertyChangedEvent("Person2");
        }
    }
}

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564403

The problem is, unless Person implements INotifyPropertyChanged, you have no way to track when a property within the person instance is changed.

A binding like this:

 <Label Text="{Binding Path=Person1.Name}"/>

Does not change the Person1 instance, but rather a property within the same instance. Unless that class implements INPC, you'll never "see" that the property has changed, and never raise your event.

Upvotes: 4

Related Questions