绑定到ViewController中嵌套CustomView的属性

时间:2018-01-28 15:45:15

标签: xamarin.ios mvvmcross

鉴于我有以下设置(简化版本,删除逻辑以添加到父视图和约束等)。

public class TestViewModel : MvxViewModel
{
  string _text;
  public string Text
  {
    get => _text;
    set
    {
      _text = value;
      RaisePropertyChanged(() => Text);
    }
  }
}


public class TestViewController : MvxViewController<TestViewModel>
  {
      CustomViewA customViewA;
      public TestViewController()
      {

      }

      public override void ViewDidLoad()
      {
          base.ViewDidLoad();

          var bindingSet = this.CreateBindingSet<TestViewController, TestViewModel>();

          bindingSet
              .Bind(customViewA)
              .For(v => v.Text)
              .To(vm => vm.Text);

          bindingSet.Apply();
      }
  }

public class CustomViewA : UIView
    {
        CustomViewB customViewB;

        public string Text
        {
            get => customViewB.Text;
            set => customViewB.Text = value;
        }
    }

    public class CustomViewB : UIView
    {
        UITextField textField;
        public string Text
        {
            get => textField.Text;
            set => textField.Text = value;
        }
    }

为什么绑定不起作用?只有当我将CustomViewB中的UITextField公开并在ViewController中直接绑定到它而不是指向Text属性的公共属性时,它似乎才有效。像这样:

bindingSet
              .Bind(customViewA.customViewB.textField)
              .For(v => v.Text)
              .To(vm => vm.Text);

我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

这取决于您的要求。

在一个方向上绑定应该有效(查看模型到视图),我已经测试了您的代码,当ViewModel属性发生更改时,更改会传播到CustomViewA并从那里传播到{{ 1}},最后到CusomViewB

然而,问题在于相反的方向(视图 - 视图模型)。当用户更新文本字段时,其UITextField属性会更改。但是,此更改没有通知

虽然属性Text指向文本字段,但它并未“绑定”到它,因此当Text的{​​{1}}更改时,属性本身不知道它和MvvmCross绑定都没有。

实际上,在控制到视图模型方向上的MvvmCross绑定基于观察事件的能力,该事件告诉绑定检查压缩源的新值。这已经针对TextField的{​​{1}}实施,它会挂钩Text事件(请参阅source code)。

您仍然可以通过手动实现自定义绑定,在视图到视图模型方向上工作。这是described in the documentation