1

For a project about train times, I would like to make sure that when I tap on UITextfield, I go to a tableview. From this I select a station from the list and he would then have to go back to the first view but he has to fill in the station in the corresponding textfield.

If someone could help me with this, this would be fantastic.

thanks in advance.

The whole project is mad in MvvmCross, IOS (Xamarin)

enter image description here

enter image description here

picciano
  • 22,341
  • 9
  • 69
  • 82
HoereeBauke
  • 544
  • 1
  • 5
  • 14

1 Answers1

0

I would probably listen to UITextFieldEditingDidBegin to figure out that the UITextField is in focus. However, this binding is not supported out of the box.

What you would then do is to grab this class: https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross/Platforms/Ios/Binding/Target/MvxUITextFieldTextFocusTargetBinding.cs which is the binding definition for UITextFieldEditingDidEnd and just change it to the UITextFieldEditingDidBegin and have it trigger a ICommand when that event fires.

This would look something like:

public class MvxUITextFieldEditingDidBeginTargetBinding : MvxTargetBinding
{
    private IDisposable _subscription;
    private ICommand _command;

    protected UITextField TextField => Target as UITextField;

    public override Type TargetType => typeof(ICommand);
    public override MvxBindingMode DefaultMode => MvxBindingMode.OneWay;

    public MvxUITextFieldEditingDidBeginTargetBinding(object target)
        : base(target)
    {
    }

    public override void SetValue(object value)
    {
        _command = value as ICommand;
    }

    public override void SubscribeToEvents()
    {
        var textField = TextField;
        if (TextField == null) return;

        _subscription = textField.WeakSubscribe(nameof(textField.EditingDidBegin), HandleEditingBegin);
    }

    private void HandleEditingBegin(object sender, EventArgs e)
    {
        if (_command == null) return;
        if (!_command.CanExecute(null)) return;

        _command.Execute(null);
    }

    protected override void Dispose(bool isDisposing)
    {
        base.Dispose(isDisposing);
        if (!isDisposing) return;

        _subscription?.Dispose();
        _subscription = null;
    }
}

Then you would need to register it in your Setup class in FillTargetFactories:

protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
    base.FillTargetFactories(registry);

    registry.RegisterCustomBindingFactory<UIControl>(
        "EditingDidEnd",
        view =>
            new MvxUITextFieldEditingDidBeginTargetBinding(view));
}

This will allow you to bind to EditingDidEnd in a binding:

set.Bind(textField).For("EditingDidEnd").To(vm => vm.SomeCommand);

You can read a bit more about custom bindings in the MvvmCross documentation: https://www.mvvmcross.com/documentation/advanced/custom-data-binding

Cheesebaron
  • 24,131
  • 15
  • 66
  • 118
  • Okay, trying to figure it out. But where do i need to place the MvxUITextFieldEditingDidBeginTargetBinding and the MvxUITextFieldTextFocusTargetBinding class? – HoereeBauke Apr 16 '18 at 09:39
  • Also VS isn't able to find the FillTargetFactories? Just to make sure, I'm working in a single view app with a class library as core. – HoereeBauke Apr 16 '18 at 17:06
  • FocusTarget binding already comes with MvvmCross, so you don't need to put it anywhere, it is just used as reference for the class I posted. The one I posted you put in your iOS App Project, because it contains iOS View code. `FillTargetFactories` is a method you override in your `Setup` class. – Cheesebaron Apr 16 '18 at 18:34