Search code examples
c#inheritanceuwpinotifypropertychangednswag

UWP with nswag INotify problem with inherited properties


I have a DotNetCore Web Api and its client is a UWP APP where client is connected with api through generated Nswag file. I have a class DropDownBase in my api side which is used as a base class for many different kind of dropdown classes, and it was made to hold the common properties across all dropdown classes. Here I will show you one of those child class called Caliber.

DropDownBase (api side)

public class DropDownBase : DefaultBaseColumn
{
    public Guid Id { get; set; }
    public string TypeName { get; set; }
}

//This class is irrelevant but putting it here for full context.
public class DefaultBaseColumn : IDefaultBaseColumn
{
    public Guid CreatedBy { get; set; }
    public DateTimeOffset Created { get; set; }
    public string CreatedByName { get; set; }
    public Guid? ModifiedBy { get; set; }
    public DateTimeOffset? Modified { get; set; }
    public string ModifiedByName { get; set; }
    [DefaultValue(true)]
    public bool IsActive { get; set; } = true;
}

Caliber (api side)

public class Caliber : DropDownBase
{  }

Now it is important to note that on client side I use this DropDownBase class to make collections and much more custom logic so that I dnt have to write redundant logic for every drop down class separately. And it works as expected.

The issue

The property TypeName exists in DropDownBase and when it is bound to UI xaml from a child object, e.g : "{x:Bind caliber.TypeName, Mode=OneWay}" and then TypeName value is changed, it does not update the value on UI so INotify system doesnt work as expected. But it works fine if the property exist directly in class Caliber instead of being inherited from a parent class.

DropDownBase (nswag client side generated file)

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class DropDownBase : DefaultBaseColumn, System.ComponentModel.INotifyPropertyChanged
{
    private System.Guid _id;
    private string _typeName;

    [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
    public System.Guid Id
    {
        get { return _id; }
        set 
        {
            if (_id != value)
            {
                _id = value; 
                RaisePropertyChanged();
            }
        }
    }

    [Newtonsoft.Json.JsonProperty("typeName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
    public string TypeName
    {
        get { return _typeName; }
        set 
        {
            if (_typeName != value)
            {
                _typeName = value; 
                RaisePropertyChanged();
            }
        }
    }


    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) 
            handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }

}

Caliber (nswag client side generated file)

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class Caliber : DropDownBase, System.ComponentModel.INotifyPropertyChanged
{


    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) 
            handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }

}

Please note that manually changing the nswwag generated file cannot be an ideal fix for my situation as we often generate these files and any manual change will be overwritten then. I just want the typename property to notify the UI that it was changed.

On client side I also have a second DropDownBase file where I add extra stuff to this class for any custom logic on client side only, because nswag generated a partial class for me its easier for me to do this, so if any suggested fix includes putting some code into this partial class, that might work for me.

DropDownBase (partial class on client side for extra code)

public partial class DropDownBase
{
    [JsonIgnore]
    public DropDownBase THIS => this;
}

Solution

  • This issue is caused by the overriding of parent class. The code in Caliber class generated by nswwag override the PropertyChanged event and RaisePropertyChanged method, which causes hide RaisePropertyChanged method inherited from base class.

    You can delete these overriding in Caliber class to solve error. But you said these code genetated automatically, and it can’t change.

    As you said, you can add the Typename property to the sub class. Or you can directly declare the object of the parent class and bind dropDownBase.TypeName.