MvxBind错误:在显示第一个屏幕之前抛出“Null对象无法转换为值类型”

时间:2013-07-17 22:11:35

标签: android xamarin.android mvvmcross

我正在使用MvvmCross将ViewModel中的数据绑定到axml布局文件中的属性。应用程序完全加载后,这些绑定可以正常工作。但是,在调试输出日志中有大量“MvxBind:Error”消息,表示“Null对象无法转换为值类型”。所有这些错误都发生在Android应用程序显示初始“SplashScreen.axml”视图之前。在那之后,所有绑定都按预期工作。

还值得注意的是,仅在将值绑定到自定义控件中的属性或通过自定义转换器传递的绑定值时才会出现这些错误。我没有看到任何问题,例如,将字符串绑定到TextView中的Text属性。

错误的示例日志输出:

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

我已经尝试检查转换器中的“value”,看它在返回任何内容之前是否为null。我也尝试将“LocationCurrentMovementViewModel.IsAlarmSignaled”初始化为默认值。这对显示的错误没有影响。

对象“LocationCurrentMovementViewModel”嵌套在与axml布局文件关联的ViewModel中。它在运行时动态设置。但是,我证实这不是问题的原因。我创建了一个临时对象,“TempBoolTrue,它只是一个设置为true的布尔变量。我用它来替换axml布局文件中的”LocationCurrentMovementViewModel.IsAlarmSignaled“。这只会导致类似的错误,而”TempBoolTrue“代替“LocationCurrentMovementViewModel.IsAlarmSignaled”。

我非常感谢您解决此问题的任何帮助。

谢谢!

----编辑----

我最近开始研究这个项目。所以,我最初设置的时候不在身边。有几个问题被曝光。

  1. 手动添加了MvvmCross资源。现在使用nuget和正确版本3.0.9添加它们。
  2. 我还发现SplashScreen.cs已被删除。 SplashScreen.axml的自定义版本将在稍后的启动过程中调用。
  3. Android应用以不规则的方式启动。看来原本有充分的理由以这种方式启动应用程序;但是,最终的解决方案可能需要改变一下。
  4. 要完成其余部分,需要一些时间。但是,你的帖子确实帮我发现了问题的根源。谢谢斯图尔特!

1 个答案:

答案 0 :(得分:0)

发生这种情况的想法

  

在Android应用程序显示初始“SplashScreen.axml”视图之前。

略微惊人 - 因为在大多数MvvmCross(包括绑定系统)被引导之前,通常会显示启动画面。


通过阅读说明,我不知道问题是什么。在显示启动画面之前,真的不确定如何获得绑定错误。

它可能与MakeSafeValue类型转换相关 - 但我“相信”这可以正确处理Null对枚举值的转换 - 请参阅MakeSafeValueTest.cs#L98上的测试用例

为了调试这个,我建议:

  1. 确保您正在使用最新的MvvmCross版本(7月13日在Mvvmcross-Binaries上为3.0.9,或在MvvmCross回购上标记为3.0.9)

  2. 尝试创建一个新的简单项目/解决方案,看看是否可以在那里重新创建问题(真的只需要1分钟就可以创建一个新的核心和droid项目进行测试)

  3. 如果在调试期间没有解决方案,那么您可以在https://github.com/slodge/MvvmCross/issues/new上提出问题,并且可以将测试存档推送到GitHub以协助调试。