Skip to content
Nicholas Ventimiglia edited this page Oct 1, 2015 · 4 revisions

Databinding

Databinding is a mechanism to 'connect' your UI widgets (buttons, input, text, lists) to 'view scripts'. This strategy is necessary for the Model-View-ViewModel architecture that is very popular in the C# world. In MVVM Your views's properties, fields and methods are 'observed' by the UI elements and any changes to your view's are communicated to the UI elements so they may update worry free.

  • Supports most major uGUI elements (Input, text, images, ect)
  • Supports observing inheritance, interfaces, structs and using DLLs
  • Bind to monobehaviours, CLR objects, INotifyPropertyChange or IObservableModel.
  • Bind to methods, fields, properties or coroutines
  • Databinding core is a dll, so bind to objects from class libraries.

View Model Logic

It is recommended that you inherit your monobehaviours from ObservableBehaviour and your clr objects from ObservableObject. These classes implement the IObservableModel interface for you. IObservable is a contract much like INotifyPropertyChange that notifies view elements and other observing objects of changes within the object. (The difference being that it includes the changed value to avoid additional reflection calls). As noted above, You do not need to inherit from anything for one-time binding, but, these interfaces are required to get the full power (dynamically changing ui elements) out of databinding.

Example View Model

Here is an example model with a single observable property. when the property changes the view (or any other listener) will receive the change event and have an opportunity to update itself.

public class MyModel : ObservableObject {

        private int _myProperty;
        public int MyProperty
        {
            get { return _myProperty; }
            set
            {
				// Prevent Stack Overflow in two way binding scenarios
                if (_myProperty == value)
                    return;

                _myProperty = value;

				// Notify Listeners
                NotifyProperty("MyProperty", value);
            }
        }
}

ProTip Writing this snippet for every property can be tedious. Use a Visual Studio Code Snippet to accelerate development. Simple add this to 'MyCodeSnippets' and in Visual Studio type 'uprop tab tab' and the snippet will scaffold out an observable property.

  • %userprofile%\documents\Visual Studio 2015\Code Snippets\Visual C#\My Code Snippets
  • %userprofile%\documents\Visual Studio 2013\Code Snippets\Visual C#\My Code Snippets
  • UPROP Code Snippet

Models vs ViewModels

Extending from ObservableBehaviour requires that you make an instance of your view in the scene (since it is an MonoBehaviour). This has the advantage of letting you set properties in your scene view. Personally, this is the path I take for most views and static services.

Extending from ObservableScriptableObject requires that you make an instance in your editor (since it is an ScriptableObject). This has the advantage of letting you set properties in your editor.

Extending from ObservableObject is my personal choice for most data objects (high scores, profiles, ect). It is a light weight CLR object which does not depend on the UnityEngine. I use observable object when I have a dynamically created object which might change from time to time (such as a User and High Score).

View Logic

Once you have your model defined and a mockup of your view using Unity's uGUI UI framework it is time to connect the two. This is done by adding the BindingContext to your UI root element and attaching binders onto the control elements.

####Binding Context

The binding context is responsible for gluing your model to your view elements. That is to say, it mediates the property values and change events between the observing UI controls and the observable model. Once set child binders will update with a listing of properties to bind to.

Binding context

This script sits at the root of your UI and operates in one of three modes.

- MonoBinding
Viewmodel is a monobehaviour (or observable behavior). Drag and drop the behavior 
into the editor field to bind to it.

- MockBinding
Viewmodel is a late bound. Use this option when you would like to set the datatype
for child binders while not actually setting the model instance. Example uses
include list controls where you may know the type of the list item but the actual
item instance is set at run time.

- Property Binding (Hierarchy Binding)
This allows you to index into a model within another model. For instance MyModel.MyUser.MyName
where MyModel is the parent viewmodel, MyUser is a child model and MyName is a property of
the child most model.

Binders

Binders sit underneath a binding context and next to their associated ui element. When the binding context is set the binders will update with a listing of valid properties and methods from the model.

There are a number of binders including InputFieldBinder, ButtonBinder, ListBinder and ImageBinders. I believe I have most major controls. If you need a custom binder inherit from BinderBase. If you feel that I have neglected a non specialized binder, let me know and I will make it.

Using a binder is straight forward. Just drag and drop the script onto the control that it will bind to. For instance if you want databinding on an Input Field include the Input Field binder as well.

Text Binder