MvvmCross数据绑定中的枚举支持

3

我有一个枚举类型的属性在视图模型中,如果该属性的值为特定的值,我想使一个标签可见。

States state;
public States State
{
    get { return this.state; }
    set
    {
        if (this.state != value)
        {
            this.state = value;
            this.RaisePropertyChanged("State");
        }
    }
}

public enum States
{
    Stopped,
    Runnning
}

这是我在用户界面上尝试的:

local:MvxBind="Visibility If(State==1, 'Visible', 'Gone')"

但它不起作用,在日志中没有显示错误。

我可以制作一个转换器,但我想知道是否可以在没有转换器的情况下完成。

如果我将State属性修改为使用int而不是Enum,则可以正常工作。 我猜这与当前如何处理枚举类型有关。

1个回答

3
在Tibet绑定插件中,类似以下语句:
 If(State==1, 'Visible', 'Gone'

由于iOS JIT的限制,并没有对其进行编译,而是进行了求值。

遗憾的是,像==这样的运算符的求值在不使用动态代码的情况下非常困难...

因此,Tibet ==运算符尝试将左右两边缩减为三种类型之一:longdoubleobject - 它通过以下方式实现:

    private Type GetLookupTypeFor(object value)
    {
        if (value == null)
            return null;
        if (value is long)
            return typeof(long);
        if (value is double)
            return typeof (double);
        return typeof (object);
    }

https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding/Combiners/MvxPairwiseValueCombiner.cs#L36获取的内容:

有了这些类型之后,它会调用下面这些方法中的一个,每个方法都使用左侧类型的 == 运算符或者如果两个类型都是 object 则使用.Equals

    protected override bool CombineDoubleAndDouble(double input1, double input2, out object value)
    {
        value = input1 == input2;
        return true;
    }
    protected override bool CombineDoubleAndLong(double input1, long input2, out object value)
    {
        value = input1 == input2;
        return true;
    }
    // ... etc

这段内容来源于 https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding/Combiners/VeryExperimental/MvxEqualToValueCombiner.cs

对于枚举类型State==1的情况,我认为左侧将被识别为object,右侧将被识别为long - 因此这些值永远不会相等,因为:

    protected override bool CombineObjectAndLong(object input1, long input2, out object value)
    {
        value = false;
        return true;
    }

在处理当前代码时,我认为让左右两边的值都变成long或者string是让测试正常运行的唯一方法。

你可以使用一个值转换器来将枚举类型转换成字符串 - 比如一个ToStringValueConverter或者一个ToLongValueConverter。然后你可以像这样使用它:

 If(ToLong(State)==1, 'Visible', 'Gone'

或者:

 If(ToString(State)=='Running', 'Visible', 'Gone'

显然,展望未来,在Mvx内部也可以改进这个领域 - 无论是在SwissTibet之外的任何地方。


非常感谢您的解释,Stuart。为什么内置ToString()转换器(甚至带有一步组合器)没有意义呢?这将使数据绑定适用于几乎任何类型。 - WriteEatSleepRepeat
没有内置的ToString转换器,因为从来没有人请求过。希望这样说有意义。在这里结束 - stackoverflow不鼓励在评论中进行后续问题和对话。 - Stuart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接