【问题标题】:mvvmcross: How to use enum values as ItemsSourcemvvmcross:如何使用枚举值作为 ItemsSource
【发布时间】:2014-05-18 04:52:37
【问题描述】:

我的模型中有以下内容:

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?

【问题讨论】:

    标签: mvvmcross


    【解决方案1】:

    编辑:更好的解决方案

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

    但是,您可以使用 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); }
    }
    

    我们要做的是创建一个 Value Converter,它将 enum 转换为用于显示的字符串,该字符串将返回 Display Name属性(如果存在)。

    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(.)。那是值转换器,. 表示当前值,即 enum

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

    【讨论】:

    • 或者更好的是,使用Enum.GetValues 方法。这将为您留下一个包含 实际 枚举值的Array,然后您无需解释任何字符串即可获得相应的值。
    • 用更好的解决方案更新答案并包含示例代码
    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多