Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android MVVMCross:绑定双向不';更新视图模型_Android_Binding_Xamarin_Mvvmcross - Fatal编程技术网

Android MVVMCross:绑定双向不';更新视图模型

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

我正在尝试绑定Xamarin.Android项目中自定义控件中的属性

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甚至不需要自定义绑定)