啊,我說得太快了!有a perfectly good solution,至少在Silverlight 3(它可能只是在3,因爲this thread表明,與此相關的東西,一個錯誤是固定在Silverlight 3)
基本上,你需要爲ItemsSource
財產單轉換器,但它可以是完全通用的,而不使用任何禁止的方法,只要您傳遞其類型爲MyEnum
的屬性的名稱即可。數據綁定到SelectedItem
完全無痛;不需要轉換器!至少,只要你不想爲每個枚舉值通過例如自定義字符串。 DescriptionAttribute
,嗯......可能需要另一個轉換器;希望我能把它變成通用的。
更新:我做了一個轉換器,它的工作原理!不幸的是,我現在必須綁定到SelectedIndex
,但沒關係。使用這些傢伙:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Data;
namespace DomenicDenicola.Wpf
{
public class EnumToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Note: as pointed out by Martin in the comments on this answer, this line
// depends on the enum values being sequentially ordered from 0 onward,
// since combobox indices are done that way. A more general solution would
// probably look up where in the GetValues array our value variable
// appears, then return that index.
return (int)value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Enum.Parse(targetType, value.ToString(), true);
}
}
public class EnumToIEnumerableConverter : IValueConverter
{
private Dictionary<Type, List<object>> cache = new Dictionary<Type, List<object>>();
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var type = value.GetType();
if (!this.cache.ContainsKey(type))
{
var fields = type.GetFields().Where(field => field.IsLiteral);
var values = new List<object>();
foreach (var field in fields)
{
DescriptionAttribute[] a = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (a != null && a.Length > 0)
{
values.Add(a[0].Description);
}
else
{
values.Add(field.GetValue(value));
}
}
this.cache[type] = values;
}
return this.cache[type];
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
有了這種結合XAML的:
<ComboBox x:Name="MonsterGroupRole"
ItemsSource="{Binding MonsterGroupRole,
Mode=OneTime,
Converter={StaticResource EnumToIEnumerableConverter}}"
SelectedIndex="{Binding MonsterGroupRole,
Mode=TwoWay,
Converter={StaticResource EnumToIntConverter}}" />
而且這種資源聲明XAML的:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ddwpf="clr-namespace:DomenicDenicola.Wpf">
<Application.Resources>
<ddwpf:EnumToIEnumerableConverter x:Key="EnumToIEnumerableConverter" />
<ddwpf:EnumToIntConverter x:Key="EnumToIntConverter" />
</Application.Resources>
</Application>
任何意見,將不勝感激,因爲我有點像XAML/Silverlight/WPF /等。新手。例如,EnumToIntConverter.ConvertBack
會變慢,所以我應該考慮使用緩存?
絕對緩存所有你與Type對象做(即GetFields()),因爲它的反射和一般被認爲是緩慢的(當然這取決於東西你的應用程序使用反射)。除了那個不錯的工作! – 2009-08-17 17:35:56
非常有幫助。謝謝。你有沒有想過把它擴展到容易翻譯的值 - 例如OrderStatus.NewOrder到「New Order」? – 2009-12-21 08:12:45
的確,上面的代碼會解析你添加到枚舉字段中的任何'DescriptionAttributes'。 – Domenic 2009-12-21 12:35:18