Let’s start with the first question: What is Dynamic Data Collection? It is the basis of LiveList in Android. In short, it runs a notification mechanism to notify the UI when an add, delete or reset is made to the list. ObservableCollection is the first thing that comes to mind for experienced developers. This is very popular in WPF for updating the UI but in Unity3D this is a bit difficult to do because mono does not provide an OnservableCollection for us.

Implementation of ObservableList

When the core of the mechanism is to generate notifications, the first mechanisms that come to mind are event and delegate, but the frequently used collection List in .NET does not provide us with such a mechanism. Therefore, we add OnAdd, OnRemove, OnInsert events to our ObservableList data structure. To notify the UI that will generate a notification when the Collection does an insertion or deletion.

The following figure shows a UI design in the Data-Driven form:

Data Driven UI UML

The codes of the list we will make will be as follows:

public class ObservableList<T>:IList<T>
{
    //... ...
    private List<T> _value=new List<T>();

    public delegate void AddHandler(T instance);
    public AddHandler OnAdd;

    public delegate void InsertHandler(int index,T instance);
    public InsertHandler OnInsert;

    public delegate void RemoveHandler(T instance);
    public RemoveHandler OnRemove;

    public void Add(T item)
    {
        _value.Add(item);
        if (OnAdd != null)
        {
            OnAdd(item);
        }
    }

    public bool Remove(T item)
    {
        if (_value.Remove(item))
        {
            if (OnRemove != null)
            {
                OnRemove(item);
            }
            return true;
        }
        return false;
    }

    public void Insert(int index, T item)
    {
        _value.Insert(index,item);
        if (OnInsert!=null)
        {
            OnInsert(index, item);
        }
    }
}

Optimizing the ObservableList

The design we have done so far is good, but it does not produce a notification during Initialization. Let’s say we initialize our list as follows:

public ObservableList<FaceBox> DataSource = new ObservableList<FaceBox>
{
    new FaceBox
    {
        Name = "Omer",
        Level = 31,
        Face = "ceceomer_v1",
        Badge = new Badge {Icon = "Star", ElementColor = "9999FFFF"}
    },
    new FaceBox
    {
        Name = "Asuman",
        Level = 32,
        Face = "YapmaAsuman",
        Badge = new Badge {Icon = "Sh*t", ElementColor = "FF1341FF"}
    }
};

Clearly speaking, OnAdd and OnRemove were not triggered so the UI failed to update when our list was Initialize or reset. We will solve this with the BindablePropety we designed earlier. We will add a Value property inside and our mechanism will follow that Value property.

public class ObservableList<T>:IList<T>
{
	//... ...
    public delegate void ValueChangedHandler(List<T> oldValue, List<T> newValue);
    public ValueChangedHandler OnValueChanged;
   
    private List<T> _value=new List<T>();
    public List<T> Value
    {
        get { return _value; }
        set
        {
            if (!Equals(_value, value))
            {
                var old = _value;
                _value = value;

                ValueChanged(old, _value);
            }
        }
    }

    private void ValueChanged(List<T> oldValue, List<T> newValue)
    {
        if (OnValueChanged != null)
        {
            OnValueChanged(oldValue, newValue);
        }
    }
}