Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Can you explain how to create a custom data binding in MvvmCross


Can you explain how to create a custom data binding in MvvmCross


Creating a custom data binding in MvvmCross involves defining how to bind a specific property of a view to a property in a view model. This is particularly useful when MvvmCross does not support the binding out of the box, such as in two-way mode or when dealing with custom views that require additional parameters. Here’s a step-by-step guide on how to create a custom data binding:

Understanding the Basics

- Target: The property on your view that you want to bind.
- Source: The property in your view model that you want to bind to.
- Target Binding: A class that defines how to bind a view property to a view model property.

Creating a Custom Target Binding

To create a custom target binding, you need to write a class that inherits from `MvxTargetBinding`. Here’s an example of how to bind a custom view's property called `MyProperty`:

csharp
public class MyViewMyPropertyTargetBinding : MvxPropertyInfoTargetBinding
{
    private bool _subscribed;

    public override MvxBindingMode DefaultMode => MvxBindingMode.TwoWay;

    public MyViewMyPropertyTargetBinding(object target, PropertyInfo targetPropertyInfo)
        : base(target, targetPropertyInfo)
    {
        // This constructor is used to initialize the binding.
    }

    protected override void SetValueImpl(object target, object value)
    {
        var view = target as MyView;
        if (view == null) return;
        view.MyProperty = (string)value;
    }

    public override void SubscribeToEvents()
    {
        var myView = View;
        if (myView == null)
        {
            MvxBindingTrace.Trace(MvxTraceLevel.Error, "Error - MyView is null in MyViewMyPropertyTargetBinding");
            return;
        }

        _subscribed = true;
        myView.MyPropertyChanged += HandleMyPropertyChanged;
    }

    private void HandleMyPropertyChanged(object sender, EventArgs e)
    {
        var myView = View;
        if (myView == null) return;
        FireValueChanged(myView.MyProperty);
    }

    protected override void Dispose(bool isDisposing)
    {
        base.Dispose(isDisposing);
        if (isDisposing)
        {
            var myView = View;
            if (myView != null && _subscribed)
            {
                myView.MyPropertyChanged -= HandleMyPropertyChanged;
                _subscribed = false;
            }
        }
    }
}

Registering the Custom Target Binding

After defining the custom target binding, you need to register it in your `Setup.cs` file by overriding the `FillTargetFactories` method:

csharp
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
    base.FillTargetFactories(registry);
    registry.RegisterPropertyInfoBindingFactory(
        typeof(MyViewMyPropertyTargetBinding),
        typeof(MyView), "MyProperty");
}

Using the Custom Binding

Once the custom binding is registered, you can use it in your views like any other binding:

csharp
var aView = new MyView();
set.Bind(aView).For("MyProperty").To(vm => vm.value);

If you want to avoid specifying the property name every time you bind, you can set a default binding name in your `Setup.cs` file.

Additional Considerations

- MvxConvertingTargetBinding: This class is useful for preventing feedback loops when using converters.
- MvxPropertyInfoTargetBinding: A subclass of `MvxConvertingTargetBinding`, it simplifies creating one-way bindings by automatically implementing the `SetValue` method based on `PropertyInfo`.
- MvxWithEventPropertyInfoTargetBinding: A shortcut for creating two-way bindings based on a specific event.

Creating custom bindings allows you to extend MvvmCross's capabilities to handle any custom view or property you might need in your application.

Citations:
[1] https://www.mvvmcross.com/documentation/advanced/custom-data-binding
[2] https://stackoverflow.com/questions/28798209/mvvmcross-binding-your-datamodel-to-your-viewmodel
[3] https://learn.microsoft.com/en-us/archive/msdn-magazine/2014/august/windows-phone-build-mvvm-apps-with-xamarin-and-mvvmcross
[4] https://blog.ostebaronen.dk/2018/01/mvvmcross-binding-target.html
[5] https://www.mvvmcross.com/documentation/getting-started/getting-started
[6] https://stackoverflow.com/questions/10700445/in-mvvmcross-how-do-i-do-custom-bind-properties
[7] https://www.mvvmcross.com/documentation/fundamentals/data-binding
[8] https://crosscuttingconcerns.com/MvvmCross-Fluent-Databinding