4

I will like to change the default binding trigger from PropertyChanged to LostFocus on a Droid EditText view:

 <EditText
                android:layout_width="fill_parent"
                android:layout_gravity="center"
                android:textSize="16dp"
                android:minWidth="168dp"
                local:MvxBind="Text SelectedCode, UpdateSourceTrigger=LostFocus" />

But I cannot find the correct syntax from the Wiki

I know this is possible within the framework but cannot find the reference.

Ideas?

TIA.

Klaus Nji
  • 18,107
  • 29
  • 105
  • 185

1 Answers1

7

The binding syntax doesn't provide UpdateSourceTrigger

The only ways to change the triggering mechanism are:

  • to provide a custom binding
  • or to provide a custom control

I'd go for custom binding - something like:

public class MvxEditTextFocusChangeTextSpecialTargetBinding
    : MvxAndroidTargetBinding
{
    protected EditText EditText
    {
        get { return (EditText)Target; }
    }

    private bool _subscribed;

    public MvxEditTextFocusChangeTextSpecialTargetBinding(EditText view)
        : base(view)
    {
    }

    protected override void SetValueImpl(object target, object value)
    {
        var editText = EditText;
        if (editText == null)
            return;

        value = value ?? string.Empty;
        editText.Text = value.ToString();
    }

    public override MvxBindingMode DefaultMode
    {
        get { return MvxBindingMode.TwoWay; }
    }

    public override void SubscribeToEvents()
    {
        var editText = EditText;
        if (editText == null)
            return;

        editText.FocusChange += HandleFocusChange;
        _subscribed = true;
    }

    private void HandleFocusChange(object sender, View.FocusChangeEventArgs e)
    {
        var editText = EditText;
        if (editText == null)
            return;

        if (!e.HasFocus)
            FireValueChanged(editText.Text);
    }

    public override Type TargetType
    {
        get { return typeof(string); }
    }

    protected override void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            var editText = EditText;
            if (editText != null && _subscribed)
            {
                editText.FocusChange -= HandleFocusChange;
                _subscribed = false;
            }
        }
        base.Dispose(isDisposing);
    }
}

registered using:

registry.RegisterCustomBindingFactory<EditText>("FocusText",
                                                        textView => new MvxEditTextFocusChangeTextSpecialTargetBinding(textView));

then used as:

 local:MvxBind="FocusText VMProperty"

For more on custom bindings, see the N=28 tutorial - http://slodge.blogspot.co.uk/2013/06/n28-custom-bindings-n1-days-of-mvvmcross.html

Stuart
  • 66,722
  • 7
  • 114
  • 165
  • One word of caution here - I just realised I took this sample from the BindingChanges 3.0.13-beta4 branch of MvvmCross - this branch introduced `SetValueImpl` and `SubscribeToEvents` - previously you used `SetValue` and put the subscribe code into the constructor. I am hoping to push 3.0.13 to stable very soon (just got one Android.Dialog issue left to resolve). – Stuart Oct 07 '13 at 12:26
  • 1
    Thanks Stuart. Was just going to add that I need to do an uppgrade as I am missing some of the aforementioned API's. I am still at 3.0.11. – Klaus Nji Oct 07 '13 at 12:31
  • something like https://gist.github.com/slodge/6867280 (not tested this - but looks vaguely right) – Stuart Oct 07 '13 at 12:44
  • Adding subscription code in the constructor and overriding SetValue works well for version 3.0.11. Thanks again. – Klaus Nji Oct 07 '13 at 13:27
  • 1
    When user changes text and then taps on back button in actionbar, binding is not updated. – Alex Sorokoletov Aug 06 '14 at 06:43
  • @AlexSorokoletov You can clear the focus OnBackPressed/OnOptionsItemSelected http://stackoverflow.com/questions/11157370 – Guillaume Mar 26 '15 at 14:27