2013-07-17 1 views
1

Я использую MvvmCross для привязки данных из ViewModel к свойствам в файле макета axml. Эти привязки работают правильно после полной загрузки приложения. Однако в журнале вывода отладки имеется большое количество сообщений «MvxBind: Error», в которых говорится, что «Объект Null не может быть преобразован в тип значения». Все эти ошибки возникают до того, как приложение Android отображает начальное представление «SplashScreen.axml». После этого все привязки работают так, как ожидалось.Ошибка MvxBind: «Объект Null не может быть преобразован в тип значения», который вызывается перед отображением первого экрана.

Следует также отметить, что эти ошибки возникают только при привязке значений к свойству в пользовательском элементе управления или значениях привязки, которые передаются через пользовательский конвертер. Я не видел никаких проблем, например, привязывая строку к свойству Text в TextView.

Пример вывода журнала ошибки:

MvxBind:Error: 17.76 Problem seen during binding execution for from LocationCurrentMovementViewModel.IsAlarmSignaled to Visibility - problem InvalidCastException: Null object can not be converted to a value type. 
07-17 20:05:51.980 I/mono-stdout(3056): MvxBind:Error: 17.76 Problem seen during binding execution for from LocationCurrentMovementViewModel.IsAlarmSignaled to Visibility - problem InvalidCastException: Null object can not be converted to a value type. 
07-17 20:05:51.980 I/mono-stdout(3056):  at System.Convert.ToType (System.Object value, System.Type conversionType, IFormatProvider provider, Boolean try_target_to_type) [0x00000] in <filename unknown>:0 
07-17 20:05:51.990 I/mono-stdout(3056): at System.Convert.ChangeType (System.Object value, System.Type conversionType, IFormatProvider provider) [0x00000] in <filename unknown>:0 
07-17 20:05:51.990 I/mono-stdout(3056): at Cirrious.MvvmCross.Binding.ExtensionMethods.MvxTypeExtensions.MakeSafeValue (System.Type propertyType, System.Object value) [0x00000] in <filename unknown>:0 
07-17 20:05:51.990 I/mono-stdout(3056): at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.MakeSafeValue (System.Object value) [0x00000] in <filename unknown>:0 
     at System.Convert.ToType (System.Object value, System.Type conversionType, IFormatProvider provider, Boolean try_target_to_type) [0x00000] in <filename unknown>:0 
    at System.Convert.ChangeType (System.Object value, System.Type conversionType, IFormatProvider provider) [0x00000] in <filename unknown>:0 
    at Cirrious.MvvmCross.Binding.ExtensionMethods.MvxTypeExtensions.MakeSafeValue (System.Type propertyType, System.Object value) [0x00000] in <filename unknown>:0 
    at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.MakeSafeValue (System.Object value) [0x00000] in <filename unknown>:0 
    at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0 
07-17 20:05:51.990 I/mono-stdout(3056): at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0 
    at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (Boolean isAvailable, System.Object value) [0x00000] in <filename unknown>:0 
[0:] MvxBind:Error: 17.76 Problem seen during binding execution for from LocationCurrentMovementViewModel.IsAlarmSignaled to Visibility - problem InvalidCastException: Null object can not be converted to a value type. 
     at System.Convert.ToType (System.Object value, System.Type conversionType, IFormatProvider provider, Boolean try_target_to_type) [0x00000] in <filename unknown>:0 
    at System.Convert.ChangeType (System.Object value, System.Type conversionType, IFormatProvider provider) [0x00000] in <filename unknown>:0 
    at Cirrious.MvvmCross.Binding.ExtensionMethods.MvxTypeExtensions.MakeSafeValue (System.Type propertyType, System.Object value) [0x00000] in <filename unknown>:0 
    at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.MakeSafeValue (System.Object value) [0x00000] in <filename unknown>:0 
    at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0 
    at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (Boolean isAvailable, System.Object value) [0x00000] in <filename unknown>:0 
07-17 20:05:51.990 I/mono-stdout(3056): at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (Boolean isAvailable, System.Object value) [0x00000] in <filename unknown>:0 

Вот связыванию, что бросает эту конкретную ошибку:

<FrameLayout 
    p1:minWidth="25px" 
    p1:minHeight="25px" 
    p1:layout_width="317dp" 
    p1:layout_height="360dp" 
    p1:id="@+id/MovementAlertOverlay" 
    p1:layout_marginTop="135dp" 
    p1:layout_marginLeft="639dp" 
    p1:background="@drawable/alert_border" 
    local:MvxBind="Visibility LocationCurrentMovementViewModel.IsAlarmSignaled,Converter=BoolToViewStates" 
/> 

Код для преобразователя:

public class BoolToViewStatesValueConverter : MvxValueConverter<bool, ViewStates> 
{ 
    protected override ViewStates Convert(bool value, System.Type targetType, object parameter, 
              System.Globalization.CultureInfo culture) 
    { 
     if (value) 
     { 
      return ViewStates.Visible; 
     } 
     return ViewStates.Gone; 
    } 
} 

Я ve попытался проверить «значение» в конверторе, чтобы увидеть, является ли оно нулевым, прежде чем возвращать что-либо. Я также попытался инициализировать «LocationCurrentMovementViewModel.IsAlarmSignaled» значение по умолчанию. Это не влияет на отображаемые ошибки.

Объект «LocationCurrentMovementViewModel» вложен в ViewModel, связанный с файлом макета axml. Он устанавливается динамически во время выполнения. Однако я подтвердил, что это не является причиной проблемы. Я создал временный объект «TempBoolTrue», который является просто логической переменной, установленной в true. Я использовал это, чтобы заменить «LocationCurrentMovementViewModel.IsAlarmSignaled» в файле макета axml. Это привело к аналогичной ошибке с «TempBoolTrue» вместо "LocationCurrentMovementViewModel.IsAlarmSignaled".

я бы очень признателен за любую помощь с решением этой проблемы.

Спасибо!

---- EDIT ----

Я недавно начал работать над этим Таким образом, меня не было вокруг, когда он был первоначально настроен. которые вышли на свет.

  1. Ресурсы MvvmCross были добавлены вручную. Теперь они добавляются с помощью nuget и в правильной версии 3.0.9.
  2. Я также обнаружил, что SplashScreen.cs был удален. Пользовательская версия SplashScreen.axml вызывается позже в процессе запуска.
  3. Приложение для Android запускается нерегулярно. Похоже, что изначально были веские причины для запуска приложения таким образом; однако результирующее решение, возможно, потребуется немного изменить.

Это займет некоторое время, чтобы разобраться в остальном. Но ваш пост помог мне открыть источник проблемы. Спасибо Стюарту!

ответ

0

Идеи этого происходящего

before the android app displays the initial "SplashScreen.axml" view.

немного тревожно - как SplashScreen обычно отображается перед большинством MvvmCross, в том числе системы связывания, является бутстрапированной.


Чтение описания, я понятия не имею, в чем проблема. На самом деле не уверен, как вы получаете ошибки привязки, пока не появится экран заставки.

Это, вероятно, связано с преобразованием в MakeSafeValue типа - но я «верю», что это может правильно обрабатывать преобразование из Null для значений перечислений - см тестовый случай на MakeSafeValueTest.cs#L98

Для отладки это, я бы рекомендовал:

  1. Убедитесь, что вы работаете с самыми последними релизами MvvmCross (3.0.9 на NuGet, 13 июля на Mvvmcross-бинарников, или помечено 3.0.9 на MvvmCross репо)

  2. Попробуйте создать новый простой проект/решение и посмотреть, можете ли вы воссоздать проблему там (для создания нового ядра и проекта дроида для тестирования требуется всего одна минута)

  3. Если во время отладки не появляется решение, вы можете поднять вопрос на https://github.com/slodge/MvvmCross/issues/new, и вы можете нажать тестовое репо на GitHub, чтобы помочь с отладкой.