Jam*_*mie 5 android xamarin.android mvvmcross xamarin
我正在使用MvvmCross和MonoDroid.
在viewmodel中的一个计时器中,我调用的每一分钟RaisePropertyChanged("MinutesRemaining")
- MinutesRemaining
都是一个整数,指定当前条目结束前的持续时间(以及是,在UI线程上调用!).
MinutesRemaining
必须TextView
使用MvvmCross.
在4.10.1
从Xamarin更新之前,应用程序将完全崩溃,并且没有错误消息打印到跟踪 - 它现在在调试时正确地破坏并在调用PropertyChanged
事件时给出以下错误:
MvxBind:Error:281.24 Problem seen during binding execution for binding Text for MinutesRemaining - problem ArgumentException: 'jobject' must not be IntPtr.Zero.
Parameter name: jobject
at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00010] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.1-branch/9d03ce3e/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:499
at Android.Widget.TextView.set_TextFormatted (ICharSequence value) [0x00034] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.1-branch/9d03ce3e/source/monodroid/src/Mono.Android/platforms/android-14/src/generated/Android.Widget.TextView.cs:1814
at Android.Widget.TextView.set_Text (System.String value) [0x00013] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.1-branch/9d03ce3e/source/monodroid/src/Mono.Android/platforms/android-14/src/generated/Android.Widget.TextView.cs:1823
at Cirrious.MvvmCross.Binding.Droid.Target.MvxTextViewTextTargetBinding.SetValueImpl (System.Object target, System.Object toSet) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Binding.Bindings.Target.MvxConvertingTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (System.Object value) [0x00000] in <filename unknown>:0
Run Code Online (Sandbox Code Playgroud)
它第一次正确绑定 - 它只RaisePropertyChanged
发生在后续调用中.相同的代码也适用于Windows 8和Windows Phone.
在用于上述场景的适配器中使用JavaFinalise修复了问题(在此处找到:MVVMCross Binding崩溃Android应用程序).我现在遇到的问题是相同的结果,但适配器中的第一个视图绑定到父视图模型中的属性(而不是项目).
用于绑定的代码如下:
public class SubjectFilterAdapter : MvxAdapter {
private EntityListFragment<TEntity, TViewModel> _owner;
public SubjectFilterAdapter(Context context, EntityListFragment<TEntity, TViewModel> owner) : base(context, (IMvxAndroidBindingContext)owner.BindingContext) {
_owner = owner;
}
protected override View GetBindableView(View convertView, object dataContext, int templateId) {
var view = base.GetBindableView(convertView, dataContext, templateId);
if (templateId == ItemTemplateId && GetPosition(dataContext) == 0) {
var set = _owner.CreateBindingSet<EntityListFragment<TEntity, TViewModel>, TViewModel>();
set.Bind(view.FindViewById<TextView>(Resource.Id.SelectedScheduleText))
.To(x => x.SelectedScheduleText).WithClearBindingKey("SelectedScheduleTextFilterBinding");
set.Apply();
}
return view;
}
protected override void JavaFinalize() {
if (this.BindingContext != null)
this.BindingContext.ClearAllBindings();
base.JavaFinalize();
}
}
Run Code Online (Sandbox Code Playgroud)
它正常工作(对于前几个更改)但在此之后抛出上述异常.使用MvvmCross 3.0.14-beta3
.
谢谢!
通过将listitem/cell绑定上下文与父上下文混合,您将进入相当高级的区域.
为了帮助尝试解释/调试您正在进行的操作,您需要了解所有父生命周期,listitem/cell生命周期以及相应MvvmCross绑定上下文的生命周期.
在父生命周期级别,这通常是Android Activity
或Fragment
.为了简单起见,我将仅Activity
用于本答案的其余部分.
这Activity
有几个关键的生命周期事件
OnCreate
仅在Activity
首次启动时调用一次OnDestroy
仅在Activity
不再显示时才调用一次.MvvmCross拦截这些事件并:
OnCreate
,它设置一个ViewModel
作为Activity
的DataContext
.用户代码 - 通常在其中膨胀的Xml代码SetContentView
- 然后创建绑定.这些绑定存储内BindingContext
的Activity
OnDestroy
,MvvmCross破坏了其中的所有绑定BindingContext
在我们感兴趣的用户界面中,Activity
拥有一个ListView
,并且ListView
有一个Adapter
设置.在这种情况下,DataContext
for ListView
和它Adapter
与它的父级相同.
在ListView
列表的生命周期内可能需要显示大量项目.随时显示的项目可能会发生变化 - 包括用户触摸操作和视图模型更改.为了显示这些项目中,ListView
询问Adapter
了View
秒.对于每个项目,它显示Adapter
耗材a View
,这些View
s可以重复使用(使用convertView
参数).但是,有时候,这些View
也不会被重用 - 在这种情况下,即使在Java/Dalvik View
被删除并且Java完成之后,有时候View对象仍然可以继续使用C#.
MvvmCross拦截其中的GetView
呼叫MvxAdapter
.对于每次调用,它不仅返回a View
而且还返回MvxListItemView
.这是一个View
添加BindingContext
- 这允许MvvmCross用户将每个绑定MvxListItemView
到其列表项DataContext
.
当a MvxListItemView
被重用时,MvvmCross很容易改变它DataContext
.
当a MvxListItemView
不被重用时 - 当它从UI中移除然后JavaFinalize
d - MvvmCross拦截OnDetachedFromWindow
事件并且它使用它来切换DataContext
到null
.它是这样做的,OnDetachedFromWindow
而不是JavaFinalize
因为保证在UI线程上进行Window调用,并且感觉(对我来说)就像一个更干净的地方来做这件事.
请注意,在最近的版本中,这种行为中的某些行为略有改变 - 但上面的描述对于v3.0.14是正确的
有了这样的背景下,它出现您正在尝试做的是创造的内容的绑定ListItemView
内BindingContext
的Activity
.
这意味着绑定实际上并没有很好地理解 - 的生命周期ListItemView
- 所以即使在ListItemView
从屏幕上移除并且(可能)最终确定后,绑定也可以说是活着的.
要解决此问题......
JavaFinalize
在这个问题的答案是"有点淘气",它会清除父Activity
过程中的S的BindingContext Finalize
的Adapter
.这可能是可以的,但它不应该是真的有必要 - Activity
自己OnDestroy
应该处理它. 归档时间: |
|
查看次数: |
4027 次 |
最近记录: |