Binding Data to UI

I know that better binding of data to the UI is on the Unity roadmap so this might not be interesting to many people as it’s work that is coming but I’ve built a system to make it easy to bind data to the UI. I hook up the UI with code like this:

DataBinder.BindLabel("StrengthValue", "Strength");
DataBinder.BindLabel("IntelligenceValue", "Intelligence");
DataBinder.BindImage("Portrait", "CharacterImage");
DataBinder.BindStyle<bool>("Button", "display", "ShowButton", (value) => value ? DisplayStyle.Flex : DisplayStyle.None);
DataBinder.BindChildrenToContainer<Equipment>("Inventory", "Inventory", (item) => new InventorySlot(item));

So you can change the image of images, text of labels, children of scrollviews or other visualelements or the style of any element based on your game data. It also automatically updates the bindings when the values change using the INotifyProperty interface. So if you remove an item from the inventory in code the UI automatically updates etc.

You can either bind directly to a property or you can use a transform e.g. Button.style.display is set to Flex or None based on a bool property.

It’s made my code much more readable. If anyone is interested I’ll put it in a public github repo.

1 Like

Looks like a really cool approach! Have you thought about using UniRx (GitHub - neuecc/UniRx: Reactive Extensions for Unity)? We’ve been using it and since then the binding became much easier.

We have a bunch of extension methods, e.g.:

[MustUseReturnValue]
public static IDisposable Bind(this TextElement textElement, IObservable<string> observable)
{
    return observable.SmartObserveOnMainThread().Subscribe(value => textElement.text = value);
}

[MustUseReturnValue]
public static IDisposable Bind(this Button button, Action action)
{
    return button.ClickedAsObservable().Subscribe(_ =>
    {
        if (button.enabledSelf)
        {
            action();
        }
    });
}

private static IObservable<Unit> ClickedAsObservable(this Button button)
{
    return Observable.FromEvent(h => button.clicked += h, h => button.clicked -= h);
}

Especially the cleaning up all the bindings when an UI element is destroyed, became much easier with this approach.

Edit:
Seeing your code on Github would be great! I’m not sure if I would use it, but reading other people’s code is fun and inspiring!