Android MVVMCross:绑定双向不';更新视图模型
我正在尝试绑定Xamarin.Android项目中自定义控件中的属性Android MVVMCross:绑定双向不';更新视图模型,android,binding,xamarin,mvvmcross,Android,Binding,Xamarin,Mvvmcross,我正在尝试绑定Xamarin.Android项目中自定义控件中的属性 public class MyControl : RelativeLayout { public ObservableCollection<string> MyProperty { get; set; } } 公共类MyControl:RelativeLayout { 公共ObservableCollection MyProperty{get;set;} } 在ViewModel端更新MyPropert
public class MyControl : RelativeLayout
{
public ObservableCollection<string> MyProperty { get; set; }
}
公共类MyControl:RelativeLayout
{
公共ObservableCollection MyProperty{get;set;}
}
在ViewModel端更新MyProperty时,它会在视图中更新MyProperty。但是,如果我在视图中更新MyProperty(我希望在ViewModel中获得更新的值),则不会发生任何事情
绑定:
public class MyControlMyPropertyTargetBinding : MvxAndroidTargetBinding
{
private bool _subscribed;
protected MyControl MyControl
{
get { return (MyControl)Target; }
}
public MyControlMyPropertyTargetBinding(MyControl target)
: base(target)
{
}
protected override void SetValueImpl(object target, object value)
{
var myControl = (MyControl)target;
myControl.MyProperty = (ObservableCollection<string>)value;
}
public override Type TargetType
{
get { return typeof(ObservableCollection<string>); }
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
public override void SubscribeToEvents()
{
base.SubscribeToEvents();
var myControl = MyControl;
if (myControl == null || myControl.MyProperty == null)
return;
myControl.MyProperty.CollectionChanged += MyPropertyOnCollectionChanged;
_subscribed = true;
}
private void MyPropertyOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
FireValueChanged(MyControl.MyProperty);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var myControl = MyControl;
if (myControl != null && myControl.MyProperty!= null && _subscribed)
{
myControl.MyProperty.CollectionChanged -= MyPropertyOnCollectionChanged;
_subscribed = false;
}
}
}
}
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterCustomBindingFactory<MyControl>("MyProperty", myProperty => new MyControlMyPropertyTargetBinding(myProperty));
}
protected override IList<Assembly> AndroidViewAssemblies
{
get
{
var assemblies = base.AndroidViewAssemblies;
assemblies.Add(typeof(MyControl).Assembly);
return assemblies;
}
}
公共类MyControlMyPropertyTargetBinding:MvxAndroidTargetBinding
{
私人股本认购;
受保护的MyControl MyControl
{
获取{return(MyControl)Target;}
}
公共MyControl MyPropertyTargetBinding(MyControl目标)
:基本(目标)
{
}
受保护的覆盖无效SetValueImpl(对象目标,对象值)
{
var myControl=(myControl)目标;
myControl.MyProperty=(ObservableCollection)值;
}
公共覆盖类型TargetType
{
获取{return typeof(observetecollection);}
}
公共覆盖MvxBindingMode默认模式
{
获取{return MvxBindingMode.TwoWay;}
}
公共覆盖无效SubscribeToEvents()
{
base.SubscribeToEvents();
var myControl=myControl;
if(myControl==null | | myControl.MyProperty==null)
回来
myControl.MyProperty.CollectionChanged+=MyPropertyOnCollectionChanged;
_订阅=真;
}
私有void MyPropertyOnCollectionChanged(对象发送方,NotifyCollectionChangedEventArgs NotifyCollectionChangedEventArgs)
{
FireValueChanged(MyControl.MyProperty);
}
受保护的覆盖无效处置(bool isDisposing)
{
基础处理(isDisposing);
if(isDisposing)
{
var myControl=myControl;
if(myControl!=null&&myControl.MyProperty!=null&&u)
{
myControl.MyProperty.CollectionChanged-=MyPropertyOnCollectionChanged;
_订阅=假;
}
}
}
}
Setup.cs:
public class MyControlMyPropertyTargetBinding : MvxAndroidTargetBinding
{
private bool _subscribed;
protected MyControl MyControl
{
get { return (MyControl)Target; }
}
public MyControlMyPropertyTargetBinding(MyControl target)
: base(target)
{
}
protected override void SetValueImpl(object target, object value)
{
var myControl = (MyControl)target;
myControl.MyProperty = (ObservableCollection<string>)value;
}
public override Type TargetType
{
get { return typeof(ObservableCollection<string>); }
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
public override void SubscribeToEvents()
{
base.SubscribeToEvents();
var myControl = MyControl;
if (myControl == null || myControl.MyProperty == null)
return;
myControl.MyProperty.CollectionChanged += MyPropertyOnCollectionChanged;
_subscribed = true;
}
private void MyPropertyOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
FireValueChanged(MyControl.MyProperty);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var myControl = MyControl;
if (myControl != null && myControl.MyProperty!= null && _subscribed)
{
myControl.MyProperty.CollectionChanged -= MyPropertyOnCollectionChanged;
_subscribed = false;
}
}
}
}
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterCustomBindingFactory<MyControl>("MyProperty", myProperty => new MyControlMyPropertyTargetBinding(myProperty));
}
protected override IList<Assembly> AndroidViewAssemblies
{
get
{
var assemblies = base.AndroidViewAssemblies;
assemblies.Add(typeof(MyControl).Assembly);
return assemblies;
}
}
受保护的覆盖无效FillTargetFactorys(IMvxTargetBindingFactoryRegistry注册表)
{
registry.RegisterCustomBindingFactory(“MyProperty”,MyProperty=>new MyControlMyPropertyTargetBinding(MyProperty));
}
受保护的重写IList AndroidViewAssembly
{
收到
{
var assemblies=base.AndroidViewAssemblies;
Add(typeof(MyControl.Assembly);
返回组件;
}
}
更新:绑定在Windows Phone上的同一控件在两个方面都能完美工作。控件本身是一个外部引用
有人知道我错过了什么吗
编辑1:我更新了目标绑定,集合已更改订阅,但未触发任何内容。ObservableCollection是通过代码而不是用户输入以编程方式更新的。我在MyControlMyPropertyTargetBinding中没有看到任何代码,当
视图更改时会通知ViewModel-例如,感谢您的回答,请参见SubscribeToEvents
。正如建议的那样,我添加了事件订阅,但没有什么比这更令人兴奋的了。如果我使用CreateBindingSet将其绑定到视图中,也会出现同样的问题(只有ViewModel>视图绑定有效)。可能是因为MyControl继承自RelativeLayout而不是View吗?还有其他想法吗?我只是不明白为什么它是单向的,尽管我的双向绑定myControl.MyProperty.CollectionChanged
并不是在改变什么-你正在改变整个myControl.MyProperty
-所以你需要某种myControl.MyPropertyChanged
事件(如果您有公共事件事件处理程序myControl.MyPropertyChanged;
,那么MvvmCross甚至不需要自定义绑定)