mvvmcross 自定义属性之间的双向绑定

Mvvmcross Two-way binding between custom properties

我不明白,如何使用双向模式在 View 和 ViewMode 之间绑定两个自定义 属性。 首先,我有一个相同的 ViewModel,如:

//ViewModel
    public class MyViewModel : MvxViewModel
    {
    ....

    private MyMode _testA

    public MyMode TestA
    {
        get => _testA;
        set { 
            _testA = value;
            RaisePropertyChanged(()=> TestA);
            }
    }


        public  MyViewModel()
        {
            TestA = MyMode.A;
        }

            ........
    }

并且在 View 中我确实绑定了我的自定义 属性:

//View
 public partial class MyView : MvxViewController<MyViewModel>
 {

    public MyMode UiTestA

     private void SetBiding()
        {
            var set = this.CreateBindingSet<MyView, MyViewModel>();
            set.Bind(this).For(x => x.UiTestA()).To(vm => vm.TestA);
            set.Apply();
        }

    private void SomeMethod()
        {
            var t1 = UiTestA; // t1 = MyMode.A;
            UiTestA = MyMode.B; // Two way binding?
            var t2 = ViewModel.TestA; // MyMode.A; 
        }
 }

如果我在 ViewModel 中更改 TestA,我可以在 View 中获取它,但我想在 View 中更改它并在 ViewModel 中找到新值。

默认情况下,MvvmCross 可以在单向模式下绑定任何 public 属性。要使 TwoWay 模式正常工作,您需要在目标绑定中创建它,该绑定允许从目标设置为源。这些称为 TargetBindings。

假设您的视图有一个名为 Hello 的 属性 和一个名为 HelloChanged 的事件。有了这两个,您就可以创建一个简单的 TargetBinding:

public class MyViewHelloTargetBinding
    : MvxConvertingTargetBinding
{
    protected MyView View => Target as MyView;

    private bool _subscribed;

    public MyViewHelloTargetBinding(MyView target)
        : base(target)
    {
    }

    private void HandleHelloChanged(object sender, EventArgs e)
    {
        var view = View;
        if (view == null) return;

        FireValueChanged(view.Hello);
    }

    public override MvxBindingMode DefaultMode = MvxBindingMode.TwoWay;

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

        target.HelloChanged += HandleHelloChanged;
        _subscribed = true;
    }

    public override Type TargetType => typeof(string);

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

        view.Hellp = (string)value;
    }

    protected override void Dispose(bool isDisposing)
    {
        base.Dispose(isDisposing);
        if (isDisposing)
        {
            var target = View;
            if (target != null && _subscribed)
            {
                target.HelloChanged -= HandleHelloChanged;
                _subscribed = false;
            }
        }
    }
}

然后您只需在 FillTargetFactories 的 Setup.cs 文件中注册您的目标绑定:

registry.RegisterCustomBindingFactory<MyView>(
    "Hello", view => new MyViewHelloTargetBinding(view));