MvvmCross,未调用特定于平台的值转换器

时间:2014-01-11 05:06:35

标签: android data-binding xamarin.android xamarin mvvmcross

我正在使用MvvmCross和Xamarin.Android。我安装了Visibility插件。在我的Android应用程序项目中,我创建了一个特定于Android的可见性转换器,它支持Invisible状态(视图未显示,但仍占用布局空间):

public class VisibleOrInvisibleValueConverter
  : MvxValueConverter<bool, ViewStates>
{
  public ViewStates Convert(bool value, Type targetType, CultureInfo cultureInfo, object parameter)
  {
    MvxTrace.Error("VisibleOrInvisibleValueConverter.Convert");
    return value ? ViewStates.Visible : ViewStates.Invisible;
  }
}

在我的.axml标记中,我使用这个转换器:

    <FrameLayout
        android:layout_width="0dip"
        android:layout_height="5dip"
        android:layout_weight="1"
        android:background="#ff0000"
        local:MvxBind="Visibility Selected, Converter=VisibleOrInvisible, FallbackValue=0" />

根据https://github.com/MvvmCross/MvvmCross/wiki/Value-Converters#referencing-value-converters-in-touch-and-droid的文档,我相信MvvmCross会自动发现这个值转换器的存在,因为它在我的UI项目中。

在运行时,无论Selected的值是什么,绑定值始终采用回退值。基于https://github.com/MvvmCross/MvvmCross/wiki/Value-Converters#referencing-value-converters-in-touch-and-droid处的文档,这意味着我的绑定源路径丢失,或者值转换器引发了异常。

不幸的是,我认为我可以排除这两种情况。对于第一种可能性,我尝试用库存MvvmCross可见性转换器替换我的自定义VisibleOrInvisible转换器,它工作正常。 (也就是说,绑定工作正常。虽然库存可见性转换器不支持我想要的行为。)无论如何,我认为这表明源路径(选定)确实存在。

对于第二种可能性,我在VisibleOrInvisible转换器的Convert函数中设置了一个断点,它永远不会被执行。我还在那里添加了一个MvxTrace调用,我从未看到跟踪消息。

虽然我的转换器应该被自动发现,但我还尝试通过覆盖Setup.cs中的ValueConverterAssemblies属性getter,将我的特定于平台的程序集显式添加到实现值转换器的程序集列表中:

protected override List<Assembly> ValueConverterAssemblies
{
  get
  {
    var toReturn = base.ValueConverterAssemblies;
    toReturn.Add(typeof (VisibleOrInvisibleValueConverter).Assembly);
    return toReturn;
  }
}

但这没有帮助。

我认为MvvmCross正在发现我的转换器。如果我故意在我的.axml文件中引用一个不存在的转换器,我会在运行时看到调试跟踪中的异常消息。但是当我指定VisibleOrInvisible转换器时,这些消息不会出现。

我的工作理论是,在执行转换器中唯一的代码 之前,调用转换器的过程中发生异常。但我不知道如何找到底线。调试跟踪中不会出现异常消息。

有一个简单的步骤,我错了吗?我非常仔细地研究了MvvmCross ValueConversion示例,我想我正在做一些示例所做的事。

1 个答案:

答案 0 :(得分:5)

我刚刚接受了ValueConversion示例,将核心csproj文件升级到profile 158,然后插入了值转换器。

这个转换器很好 - 我可以在转换器列表中看到它:

    protected override void InitializeLastChance ()
    {
        base.InitializeLastChance ();

        var registry = Mvx.Resolve<IMvxValueConverterLookup> ();
        var f = registry.Find("VisibleOrInvisible");
        Mvx.Trace ("Custom converter was found : {0}", f != null);
    }

然而,当我尝试使用它时,我看到有关enum / bool / value类型映射的绑定错误...所以我可以看到存在一些问题......


经过一番挖掘,似乎这个问题的原因是因为你的ValueConverter实现了一个不寻常的public ViewStates Convert方法,而不是覆盖基类Convert方法。为了解决这个问题,我将转换器更改为:

public class VisibleOrInvisibleValueConverter
    : MvxValueConverter<bool, ViewStates>
{
    protected override ViewStates Convert (bool value, Type targetType, object parameter, CultureInfo culture)
    {
        MvxTrace.Error("VisibleOrInvisibleValueConverter.Convert");
        return value ? ViewStates.Visible : ViewStates.Invisible;
    }
}

有关使用MvxValueConverter<...>助手创作值转化器的更多信息,请参阅https://github.com/MvvmCross/MvvmCross/wiki/Value-Converters#using-the-mvxvalueconverter-helper(如果某个其他样本或文档某处有错误的样本,那么“抱歉”,请指出任何人拥有它所以他们可以解决它)

此外,您可能会发现MvxValueConverter的来源很有帮助 - 希望能够非常直接地了解IMvxValueConverter的实施方式:https://github.com/MvvmCross/MvvmCross/blob/v3.1/CrossCore/Cirrious.CrossCore/Converters/MvxValueConverter.cs


解决了这个问题后,这个问题提出的下一个挑战是如何使用FallbackValue。我没有完全分析我从这个问题中看到的跟踪,但我确实尝试了一些其他FallbackValue语法示例 - 这些似乎都正常工作:

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="200dp"
    android:background="#ff0000"
    local:MvxBind="Visibility VisibleOrInvisible(ThisWillNotBeFound), FallbackValue=Visible"     />


<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="200dp"
    android:background="#ff0000"
    local:MvxBind="Visibility VisibleOrInvisible(ThisWillNotBeFound), FallbackValue=Invisible"     />


<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="200dp"
    android:background="#ffff00"
    local:MvxBind="Visibility VisibleOrInvisible(ThisWillNotBeFound, FallbackValue=true)" />

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="200dp"
    android:background="#0000ff"
    local:MvxBind="Visibility VisibleOrInvisible(ThisWillNotBeFound, FallbackValue=false)" />

我不确定当前数字回退值是否适用于此案例 - 怀疑它需要更多调查(将记录为潜在问题)。