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));
我不明白,如何使用双向模式在 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));