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

标签 android data-binding xamarin.android xamarin mvvmcross

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

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 的值是什么,绑定(bind)值始终采用回退值。基于https://github.com/MvvmCross/MvvmCross/wiki/Value-Converters#referencing-value-converters-in-touch-and-droid处的文档,这意味着要么我的绑定(bind)源路径丢失,要么值转换器抛出异常。

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

对于第二种可能性,我在 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 示例,并且我认为我正在执行该示例所做的所有操作。

最佳答案

我刚刚获取了 ValueConversion 示例,将核心 csproj 文件升级到配置文件 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);
    }

但是,当我尝试使用它时,我看到了有关枚举/ bool /值类型映射的绑定(bind)错误...所以我可以看到存在一些问题...


经过一番挖掘,这个问题的原因似乎是因为您的 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)" />

我不确定当前的数字后备值是否适用于这种情况 - 怀疑它需要更多调查(将记录为潜在问题)。

关于android - MvvmCross,未调用特定于平台的值转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21058744/

相关文章:

java - 平滑位图旋转 android SurfaceView

android - iOS和Android安装(直接测试)

wpf - 在代码中而不是 XAML 中设置 DataContext 有什么好处?

xamarin.android - 在 xamarin Android 应用程序中更改显示语言

android - Mono for Android - 它是如何工作的?

android - 非自定义签名的 APK(通过调试生成)运行正常但自定义签名的 APK(发布)不起作用的可能原因是什么?

android - 应用启动后如何去除AppBar阴影

安卓: "change/intercept network settings and traffic"权限

c# - 我可以使用数据绑定(bind)格式化事件来有条件地检查复选框吗?

c# - 将 DataGridComboBoxColumn 与模型绑定(bind)