mvvmcross:如何将枚举值用作ItemsSource

时间:2014-05-16 20:43:33

标签: mvvmcross

我的模型中有以下内容:

public class Equipment
{
    public enum Type
    {
        Detector,
        VegetationClearance,
        Removal,
        Engaging
    }
}

在视图模型中:

    private Equipment.Type _equipmentType;
    public Equipment.Type EquipmentType
    {
        get { return _equipmentType; }
        set
        {
            _equipmentType = value;
            RaisePropertyChanged(() => EquipmentType);
        }
    }

我想将这些值用作ItemsSource,以便用户可以从枚举中进行选择:

    <Mvx.MvxSpinner
        android:id="@+id/type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        local:MvxBind="ItemsSource Equipment.Type; SelectedItem TypeSelection" />

这根本不起作用。有没有办法将枚举绑定为ItemsSource?

1 个答案:

答案 0 :(得分:7)

编辑:更好的解决方案

正如安德斯评论的那样,Enum.GetValues()可能是一个更好的主意。绑定到枚举的问题之一是标识符不能包含空格,因此默认情况下,绑定不会为您提供良好的可读字符串。

但是,您可以使用Display属性修饰枚举。参考 System.ComponentModel.DataAnnotations

public class Equipment
{
    public enum Type
    {
        Detector,
        [Display(Name="Vegetation Clearance")]
        VegetationClearance,
        Removal,
        Engaging
    }
}

现在将以下属性添加到ViewModel:

public IEnumerable<Equipment.Type> EquipmentTypes
{
    get { return Enum.GetValues(typeof(Equipment.Type)).Cast<Equipment.Type>(); }
}

private Equipment.Type _selectedType;
public Equipment.Type SelectedType
{
    get { return _selectedType; }
    set { _selectedType = value; RaisePropertyChanged(() => SelectedType); }
}

我们要做的是创建一个值转换器,将枚举转换为字符串以便显示,它将返回显示名称属性(如果存在)。

public class EnumDisplayNameValueConverter : MvxValueConverter
{
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return GetEnumDisplayName((Enum)value);
    }

    public static string GetEnumDisplayName(Enum value)
    {
        var t = value.GetType();
        var ti = t.GetTypeInfo();
        var fi = ti.DeclaredFields.FirstOrDefault(x => x.Name == value.ToString());

        var attributes = (DisplayAttribute[])fi.GetCustomAttributes(typeof(DisplayAttribute), false);

        if (attributes != null && attributes.Length > 0)
        {
            return attributes[0].Name;
        }
        return value.ToString();
    }
}

要使用数值转换器,您需要在微调器中指定项目模板和下拉模板:

<Mvx.MvxSpinner
    android:id="@+id/type"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    local:MvxItemTemplate="@layout/spinneritem"
    local:MvxDropDownItemTemplate="@layout/spinnerdropdownitem"
    local:MvxBind="ItemsSource EquipmentTypes; SelectedItem SelectedType" />

创建spinneritem / spinnerdropdownitem布局:

<?xml version="1.0" encoding="utf-8" ?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    local:MvxBind="Text EnumDisplayName(.)" />

请注意,我们绑定到EnumDisplayName(.)。这是值转换器,.表示当前值,即枚举

我在GitHub上添加了一个示例。 https://github.com/kiliman/MvxSpinnerEnumSample