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

时间:2017-08-16 06:33:47

标签: c# mvvm binding mvvmcross two-way

我无法理解,如何在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中找到新值。

1 个答案:

答案 0 :(得分:1)

默认情况下,MvvmCross可以在OneWay模式下绑定任何公共属性。要使TwoWay模式工作,您需要创建允许从Target设置为Source的目标绑定。这些被称为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));