mvvmcross: How to use enum values as ItemsSource
mvvmcross
Solution
EDIT: Better solution
As Anders commented, `Enum.GetValues()` is probably a better idea. One of the issues in binding to enums is that the identifier can't include spaces, so by default, binding will not give you a nice readable string.
However, you can decorate your enum with a `Display` attribute. Reference System.ComponentModel.DataAnnotations.
public class Equipment
{
public enum Type
{
Detector,
[Display(Name="Vegetation Clearance")]
VegetationClearance,
Removal,
Engaging
}
}
Now add the following properties to your 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); }
}
What we are going to do is create a Value Converter that converts an enum into a string for display that will return the Display Name attribute if present.
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();
}
}
In order to use the value converter, you'll need to specify the item template and drop down template in your spinner:
<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" />
And create the spinneritem/spinnerdropdownitem layouts:
<?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(.)" />
Notice that we bind to `EnumDisplayName(.)`. That is the value converter and the `.` means the current value which is the enum.
I've added a sample on GitHub. https://github.com/kiliman/MvxSpinnerEnumSample
Problem
I have the following in my model: ``` public class Equipment { public enum Type { Detector, VegetationClearance, Removal, Engaging } } ``` And in the view model: ``` private Equipment.Type _equipmentType; public Equipment.Type EquipmentType { get { return _equipmentType; } set { _equipmentType = value; RaisePropertyChanged(() => EquipmentType); } } ``` And I want to use the values as an ItemsSource so that the user can select from the enumeration: ``` <Mvx.MvxSpinner android:id="@+id/type" android:layout_width="wrap_content" android:layout_height="wrap_content" local:MvxBind="ItemsSource Equipment.Type; SelectedItem TypeSelection" /> ``` This doesn't work at all. Is there a way to bind an enumeration as an ItemsSource?