Question

When I change the content of an UITextField.Text "by hand", the change is not reflected to the viewmodel - the setter method is not called.

In my view model

private string _amount;
public string Amount
{
  get { return _amount; }
  set { _amount = value; RaisePropertyChanged(() => Amount); }
}

In my view

var _amount = new UITextField() { TranslatesAutoresizingMaskIntoConstraints = false };
View.AddSubview(_amount);
var set = this.CreateBindingSet<View, core.ViewModels.ViewModel>();
set.Bind(_amount).To(vm => vm.Amount);
set.Apply();
_amount.Text = "something";

Amount in the viewmodel is not updated, but if I type "something" into this textfield, then the viewmodel is updated.

I tried

_amount.WillChangeValue("Text");
_amount.Text = "something";
_amount.DidChangeValue("Text");

but that did'nt work.

How do can the view tell mvvmcross that the field is updated?

Edit: Solved by a custom binding listening on UITextField changes via an observer.

Was it helpful?

Solution

MvvmCross binds to Text using the delegate/event EditingChanged from objC - see https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding.Touch/Target/MvxUITextFieldTextTargetBinding.cs#L54 - this is why no event fires when you change the text.

One way around this could be to use an inherited control and a new property instead - e.g.

 [Register("MyTextField")]
 public class MyTextField : UITextField
 {
     public MyTextField() {
        HookEvent();
     }

     public MyTextField(IntPtr ptr) {
        HookEvent();
     }

     // other ctors as needed

     private void HookEvent() {
        EditingChanged += (s, e) => MyTextChanged.Raise(this);
     }

     public string MyText {
        get { return Text; }
        set { Text = value; MyTextChanged.Raise(this); }
     }

     public event EventHandler MyTextChanged;
 }

This would allow you to use MyTextField in place of UITextField and MyText in place of Text

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top