Reputation:
I can't understand, how can I bind two custom property between View and ViewMode with Two-Way mode. First I have a same ViewModel like:
//ViewModel
public class MyViewModel : MvxViewModel
{
....
private MyMode _testA
public MyMode TestA
{
get => _testA;
set {
_testA = value;
RaisePropertyChanged(()=> TestA);
}
}
public MyViewModel()
{
TestA = MyMode.A;
}
........
}
And in View I do bind with my custom property:
//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;
}
}
If I change TestA in ViewModel, I can get this in View, but I want change it in View and find new value in ViewModel.
Upvotes: 2
Views: 1328
Reputation: 24460
Per default MvvmCross can bind any public properties, in OneWay mode. To get TwoWay mode working you need to create at target binding which allows to set from Target to Source. These are called TargetBindings.
Lets say your view has a property called Hello
and an event called HelloChanged
. With these two in hand you can create a simple 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;
}
}
}
}
Then you just need to register your target binding in your Setup.cs file in FillTargetFactories:
registry.RegisterCustomBindingFactory<MyView>(
"Hello", view => new MyViewHelloTargetBinding(view));
Upvotes: 1