How does it work?

Once you’ve created your model and implemented INotifyPropertyChanged you’re ready to create your first Bindable object.

Every Bindable object has a DataContext property containing the model. Bindable is a generic class so, in order to create your Bindable object, you will have to inherit from Bindable and use your model’s type as the template type.

//this is a base class that will help us implement INotifyPropertyChanged
public class PropertyChangedBase: INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

//model implementing INotifyPropertyChanged
public class MyModel : PropertyChangedBase
{

    #region [Name]

        public const string NAME = "Name";
        private string _name;
        public string Name {
            get{ return _name;}
            set {
                if (_name == value)return;
                _name = value;
                OnPropertyChanged (NAME);
            }
        }

    #endregion

    #region [Sprite]

        public const string SPRITE = "Sprite";
        private Sprite _sprite;
        public Sprite Sprite {
            get{ return _sprite;}
            set {
                if (_sprite == value)return;
                _sprite = value;
                OnPropertyChanged (SPRITE);
            }
        }

     #endregion

    public MyModel(string name, Sprite sprite){
            _name = name;
            _sprite = sprite;
    }

}

//Bindable class that will manage model changes.
public class MyBinder: Bindable<MyModel>
{

    public Image SourceImage;
    public Text Name;

    public void SetBindingName()
    {
        SourceImage.sprite= DataContext.Sprite;
        name = DataContext.Name;
        Name.text = DataContext.Name;
    }
}

As you can see in the code above, I’ve written a little base class to help you implement easily the INotifyPropertyChanged interface.

Bindable class runs under a few conventions:

  • Void methods starting with “SetBinding” and followed by the name of a Property will get automatically invoked everytime the value of the property changes, or more precisely, whenever the OnPropertyChanged method is invoked (if you have correctly implemented the INotifyPropertyChanged interface these will be equivalent).

  • The casing of the method is very important so if your property name is “age“, you will have to name your method “SetBindingage“. Otherwise it won’t work.

  • It’s also important to note that all the methods starting with “SetBinding” will be triggered everytime the DataContext property is set. This can be useful when we need to do something but only every time the DataContext property is set. I use to create a method called SetBindingAll (All is not a property, if fact it can’t exist a property with that name if we want it to work that way) and initialize things there.

  • If you want to create a Binding method for a property of a inner object you can. Imagine you have an object with another object which implements the INotifyPropertyChanged interface and you want to get notified. All you have to do is follow the standard convention but instead of the name of the property you have to put the name of the property containing the object (in your main object) + “_” + the name of the property you want to bind to; i.e. SetBindingMyInnerObject_Name. Try not to use underscores in your model properties unless necessary.

  • If you raise a PropertyChanged of a property called “all” all SetBinding methods will be invoked as if the datasource have been set. Imagine, in our code above, that our model’s Sprite property invokes OnPropertyChanged(“all”) instead of OnPropertyChanged(SPRITE). This would execute SetBindingName in our Binder.

  • SetBinding methods ended with “Command”, unless other SetBindingMethods, will only get executed once the property value has changed but not when DataContext property is set.