Search code examples
c#windows-phone-8mvvmdatacontract

MVVM: Raise PropertyChanged event for a DataContract class members


I want to raise PropertyChanged event for a model with DataContract. Initially I did this

[DataContract]
public partial class User : INotifyPropertyChanged
{
    [DataMember(Name="username")]
    public string Username
    {
        get
        {
            return this.Username;
        }
        set
        {
            this.Username = value;
            RaisePropertyChanged("Username");
        }
    }
}

which gave StackOverflow Exception beacause of Infinite Recursion.

So the solution I come up with is

[DataContract]
public partial class User : INotifyPropertyChanged
{
    private string _Username { get; set; }
    [DataMember(Name="username")]
    public string Username
    {
        get
        {
            return this._Username;
        }
        set
        {
            this._Username = value;
            RaisePropertyChanged("Username");
        }
    }
}

Although this reflects the Username value to the control binding to "Username", this doesn't look the best way to me. Something is wrong. Also my model has approx 30-40 fields. Is this the right approach or can someone please suggest me a better way.

Thanks


Solution

  • I'd be so tempted to use caller-member-name here (if it is in your target framework):

    private string _username;
    [DataMember(Name="username")]
    public string Username
    {
        get { return _username; }
        set { SetField(ref _username, value); }
    }
    
    private void SetField<T>(ref T field, T value,
        [CallerMemberName] string memberName = null)
    {
        if(!EqualityComparer<T>.Default.Equals(field,value))
        {
            field = value;
            RaisePropertyChanged(memberName);
        }
    }
    

    If caller-member-name isn't supported:

    [DataMember(Name="username")]
    public string Username
    {
        get { return this._Username; }
        set { SetField(ref _Username, value, "Username"); }
    }