2016-04-30 1 views
0

Я создал приложение для Android с Xamarin и MvvmCross. Я хочу привязать некоторые виды (текст, редактирование текста, кнопки) к моей ViewModel. Пока ничего странного. Но мои привязки не применяются ... Когда я использую типизированный FindViewById, я не получаю трассированную ошибку, но привязки не применяются.MvvmCross: пустая цель привязки передана MvxTargetBindingFactoryRegistry

При запуске приложения, у меня есть следующий след:

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" /> 

Получатели и сеттеры моих свойств используют метод RaiseAndSetIfChanged:

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

Я один и тот же класс LinkerPleaseInclude чем LinkerPleaseInclude исходного класса. Моя настройка наследуется от MvxAndroidSetup класс И на других моделях ViewModels привязки применяются правильно.

ответ

1

Необходимо указать base.OnCreate(bundle); до SetContentView, так как ViewModel расположен и подключен внутри этого вызова. Неспособность сделать это, очевидно, даст вам точные ошибки, которые вы видите. Источник будет null и не будет привязан к цели.

Так что вы можете сделать:

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, чтобы начать с.

0

Я не думаю, что вам нужно связать два раза, удалите эти строки:

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);

+0

Уверен, у меня может быть оговорка: я использовал разные подходы, которые я знаю. У меня есть строка, указанная в моем AXML-файле. –

+0

Не беспокойтесь, как правило, на Android я склонен делать привязки в xaml, если это не что-то необычное. –

1

The предупреждения

MvxBind:Error: 2,20 Empty binding target passed to MvxTargetBindingFactoryRegistry MvxBind:Warning: 2,20 Failed to create target binding for binding for Text

вызваны var referenceTextView = FindViewById(Resource.Id.referenceEditView); в результате referenceTextView быть типа View.

MvvmCross ищет привязки по умолчанию целевой свойства типа TTarget при вызове Bind<TTArget>безFor(targetProperty). Это просто посмотреть в таблице как:

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

В вашем случае TTarget является View вместо TextView, потому что вы передаете его в bindingsSet.Bind(referenceTextView) Wich неявная вызов bindings.Bind<View>(btnNumber). View не имеет целевого свойства привязки по умолчанию.Вы должны установить его в явном виде, как

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

или использовать набранный FindViewById<TextView>.

+0

Возможно, у меня есть оговорка. Я использовал разные подходы, которые я знаю: я использовал типизированный и нетипизированный метод FindViewById. –

+0

Хорошо, тогда, как сказал Cheesebaron, и переместите 'base.OnCreate (bundle)' в начало функции (вызовите его перед всем остальным). –