INotifyPropertyChange without boilerplate code in Xamarin.Forms

Implementing INotifyPropertyChange is pretty straightforward. Usually, you create a base ViewModel class which implements it and which usually contains RaisePropertyChanged method:

public abstract class BaseViewModel : INotifyPropertyChanged
{
    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(
        [CallerMemberNamestring propertyName = )
    {
        PropertyChanged?.Invoke(thisnew PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

Now you can extend the BaseViewModel and use it this way:

public class UserViewModel : BaseViewModel
{
    private string login;
    public string Login
    {
        get
        {
            return login;
        }
        set
        {
            if (login == value)
                return;
            login = value;
            RaisePropertyChanged();
        }
    }
    private string password;
    public string Password
    {
        get
        {
            return password;
        }
        set
        {
            if (password == value)
                return;
            password = value;
            RaisePropertyChanged();
        }
    }
}

For very small applications it can be a good enough approach, however, in bigger applications it turns into a lot of boring boilerplate code. Here is where NotifyPropertyChanged.Fody comes into play! With this nice package our code will turn into:


[ImplementPropertyChanged]
public abstract class BaseViewModel {}

public class UserViewModel : BaseViewModel
{
    public string Login { getset; }
    public string Password { getset; }
}

Easy as it is! I highly recommend to get familiar with the documentation as it contains a lot of useful information about more advanced flows. For example, if you need to RaisePropertyChange for dependent properties or to skip equality comparison.

UIDatePicker Countdown mode bug and solution in Xamarin.Forms

Problem

Show hh:mm:ss picker on iOS using Xamarin.Forms.

Goal

Extend Picker view in order to achieve the next result:

Solution

First I tried to keep it simple: to give up on seconds and use UIDatePicker in UIDatePickeCountDownMode. So the end result will look like this:

I achieved it by extending the DatePicker and it’s DatePickerRenderer and changing the mode as described above. However, I discovered that ‘datePickerValueChanged’ is being called only on a second iteration with the values. The issue was successfully reproduced in Swift, so it’s not a Xamarin bug. The Swift version can be found here.
After spending some time understanding the issue described above, I found an example on StackOverflow, thanks to Mathieu who shared his solution. His example was based on XLabs, so I removed the dependency and shared it with the community.
The code can be found on GitHub.

JSON.net Mastering enums

Problem

Legacy backend API endpoint returns JSON with units in an uncommon manner.
Instead of returning the measurement system “imperial” or “metric” it returns “kgs” or “lbs”.

Goal

Using JSON.net deserialize & serialize “kgs” to “metric” and “lbs” to “imperial” in our front-end app.

Solution

The solution is pretty simple. We have to define an enum, with “EnumMember” attributes on each element and use “StringEnumConverter” as preferred JsonConvertor. Here is the full and working example:

using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace JSONnetEnums
{
    class Program
    {
        static void Main(string[] args)
        {
            var deserializedObj = 
                JsonConvert.DeserializeObject<Foo>(“{\”Unit\”:\”kgs\”});
            Console.WriteLine(deserializedObj.Unit);
            // Output: Metric

            var serializedObj = 
                JsonConvert.SerializeObject(new Foo { Unit = Unit.Imperial });
            Console.WriteLine(serializedObj);
            // Output: {“Unit”:”lbs”}
        }
    }

    class Foo
    {
        public Unit Unit { getset; }
    }

    [JsonConverter(typeof(StringEnumConverter))]
    enum Unit
    {
        [EnumMember(Value = kgs)]
        Metric,
        [EnumMember(Value = lbs)]
        Imperial
    }
}

JSON.net snake case notation naming strategy

Communicating with backend in JSON can be challenging.
In case of C# model which by convention should be in CamelCase notation and backend which is using snake_notation we can easily solve the problem with Json.NET.

For example, we have the next model:

public class Model
{
public string FooBar { get; set; }
}

and we want it to be serialised to: { “foo_bar”: “” }
We could use an attribute:

[JsonProperty(PropertyName = "foo_bar")]
public string FooBar { get; set; }

That will work, however, if we want to generalise this strategy we should create a JsonSerializerSettings with DefaultContactResolver which is using SnakeCaseNamingStrategy and to use it while serialisation/deserialization:

public class JsonCoverter : IJsonConverter
{
private static JsonSerializerSettings defaultJsonSerializerSettings =
new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
}
};

public T Deserialize(string json) =>
JsonConvert.DeserializeObject(json, defaultJsonSerializerSettings);

public string Serialize(object obj) =>
JsonConvert.SerializeObject(obj, defaultJsonSerializerSettings);

}

Using the JsonConverter globally will solve the different notation problem.