MvvmCross :传递给 MvxTargetBindingFactoryRegistry 的空绑定目标



我用Xamarin和MvvmCross创建了一个Android应用程序。我想将一些视图(文本、编辑文本、按钮(绑定到我的视图模型。到目前为止,没有什么奇怪的。但是我的绑定不适用...当我使用键入的 FindViewById 时,我没有收到跟踪错误,但绑定不适用。

当我运行应用程序时,我有以下跟踪:

MvxBind:Error: Empty binding target passed to MvxTargetBindingFactoryRegistry
MvxBind:Warning: Failed to create target binding for binding for TextProperty

我对OnCreate(Bundle bundle)空的覆盖是:

SetContentView(Resource.Layout.Reference);
var referenceTextView = FindViewById(Resource.Id.referenceEditView); // untyped FindViewById
var siteTextView = FindViewById<TextView>(Resource.Id.siteTextView); // typed FindViewById<T>
//var goButton = FindViewById<Button>(Resource.Id.goButton);
var bindingsSet = this.CreateBindingSet<ReferenceView, ReferenceViewModel>();
bindingsSet.Bind(referenceTextView).To(vm => vm.Reference).Mode(MvxBindingMode.TwoWay);
bindingsSet.Bind(siteTextView).To(vm => vm.Site);
//bindingsSet.Bind(goButton).To(vm => vm.GoCommand);
bindingsSet.Apply();
base.OnCreate(bundle);

我尝试在 AXML 中做:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/siteTextView"
    android:text="####"
    local:MvxBind="Text Site"
    android:gravity="center" />
<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/referenceTextView"
    android:hint="Numéro de dossier"
    local:MvxBind="Text Reference" />
<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Accéder"
    android:id="@+id/goButton"
    local:MvxBind="Click GoCommand" />

我的属性的getters和setter使用RaiseAndSetIfChanged方法:

private string _reference;
public string Reference
{
    get { return _reference; }
    set { this.RaiseAndSetIfChanged(ref _reference, value, () => Reference); }
}

我有相同的LinkerPleaseInclude类与LinkerPlease包括原始类。我的设置继承自MvxAndroidSetup类在其他 ViewModel 上,绑定应用正确。

您需要

SetContentView之前调用base.OnCreate(bundle);,因为 ViewModel 位于该调用中并附加。如果不这样做,显然会给您带来您看到的确切错误。源将为空,并且不会绑定到目标。

因此,您可以执行以下操作:

base.OnCreate(bundle);
SetContentView(Resource.Layout.Reference);

并将所有绑定都放在 AXML 中。或者,您可以执行另一种方法,在后台设置绑定:

base.OnCreate(bundle);
SetContentView(Resource.Layout.Reference);
var referenceTextView = FindViewById<TextView>(Resource.Id.referenceEditView);
var siteTextView = FindViewById<TextView>(Resource.Id.siteTextView);
var bset = this.CreateBindingSet<ReferenceView, ReferenceViewModel>();
bset.Bind(referenceTextView).To(vm => vm.Reference);
bset.Bind(siteTextView).To(vm => vm.Site);
bset.Apply();

只要确保首先打电话给base.OnCreate

警告

MvxBind:错误: 2,20 空绑定目标传递到 MvxTargetBindingFactoryRegistry Mvx绑定:警告:2,20 无法为文本绑定创建目标绑定

var referenceTextView = FindViewById(Resource.Id.referenceEditView);导致referenceTextView属于 View 型引起的。

MvvmCross 在调用 Bind<TTArget> 搜索 TTarget 类型的默认绑定目标属性,而不For(targetProperty) 。这只是在表格中的查找,例如:

TTarget       Property
----------------------
TextView      Text
Button        Click
...           ...  

在你的例子中TTargetView而不是TextView,因为你把它传递到bindingsSet.Bind(referenceTextView)这是bindings.Bind<View>(btnNumber)的隐式调用。 View没有默认的绑定目标属性。你必须明确地设置它,就像

bindings.Bind(btnNumber).For("Text")

或使用键入的FindViewById<TextView>

我认为

您不需要绑定两次,请删除以下行:

var referenceTextView = FindViewById(Resource.Id.referenceEditView); // untyped FindViewById
var siteTextView = FindViewById<TextView>(Resource.Id.siteTextView); // typed FindViewById<T>
//var goButton = FindViewById<Button>(Resource.Id.goButton);
var bindingsSet = this.CreateBindingSet<ReferenceView, ReferenceViewModel>();
bindingsSet.Bind(referenceTextView).To(vm => vm.Reference).Mode(MvxBindingMode.TwoWay);
bindingsSet.Bind(siteTextView).To(vm => vm.Site);
//bindingsSet.Bind(goButton).To(vm => vm.GoCommand);
bindingsSet.Apply();

所以你的创作就是这样的:

SetContentView(Resource.Layout.Reference);
base.OnCreate(bundle);

并将绑定保留在 axml 文件中。

确保在 xaml 文件的顶部有以下内容:

xmlns:local="http://schemas.android.com/apk/res-auto"

此外,如果您在 cs 文件中执行绑定,则默认情况下 MvvmCross 绑定模式为 TwoWay。所以你不需要.Mode(MvxBindingMode.TwoWay);

最新更新