我刚刚开始玩Silverlight,一个简单的事情就像绑定一个Combobox一样让我疯狂。我现在阅读了很多文章,但没有一篇真正解决我为Silverlight 2做过的问题,而且似乎没有用。
假设我有一个实体对象“User”,它有一个“UserStatus”字段。在数据库中,UserStatus字段定义为byte,在代码中定义为:
public enum UserStatus : byte
{
Active = 1,
Locked = 2,
Suspended = 3,
}
当ADO.NET实体框架创建用户实体时,它将UserStatus字段保留为byte。所以,为了解决这个问题,我偶然发现了IValueConverter并实现了以下内容:
public class EnumConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
switch (parameter.ToString())
{
case "UserStatus":
return ((UserStatus)value).ToString();;
}
return "?";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
现在,我还需要为Combobox提供一个ItemSource,所以我实现了这个:
internal static class EnumValueCache
{
private static readonly IDictionary<Type, object[]> Cache = new Dictionary<Type, object[]>();
public static object[] GetValues(Type type)
{
if (!type.IsEnum)
throw new ArgumentException("Type '" + type.Name + "' is not an enum");
object[] values;
if (!Cache.TryGetValue(type, out values))
{
values = type.GetFields()
.Where(f => f.IsLiteral)
.Select(f => f.GetValue(null))
.ToArray();
Cache[type] = values;
}
return values;
}
}
public class EnumValuesConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
switch (parameter.ToString())
{
case "UserStatus":
return EnumValueCache.GetValues(typeof(UserStatus));
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
最后,这就是我将它添加到我的XAML的方式:
<ComboBox ItemsSource="{Binding UserStatus, Mode=TwoWay, Converter={StaticResource EnumValuesConverter}, ConverterParameter='UserStatus'}"
SelectedItem="{Binding UserStatus, Mode=TwoWay, Converter={StaticResource EnumConverter}, ConverterParameter='UserStatus'}" />
现在发生的事情是ItemsSource被正确绑定,我看到下拉列表中的所有选项,但是,未设置SelectedItem。 即使我尝试手动将SelectedItem设置为=“1”或“活动”,它们都不起作用。 任何人都可以帮助我并告诉我什么是错的,为什么我似乎无法获得SelectedItem设置?
谢谢,
汤姆
答案 0 :(得分:2)
我可以看到您的代码存在两个问题。
首先,在silverlight 3中,ComboBox通过object.Equals方法将SelectedItem中的对象与ItemsSource中的对象集匹配。但是,您的GetValues
方法返回一个Boxed枚举值数组。而你的EnumConverter
会返回一个字符串。因此,您要求Silverlight将字节与字符串进行比较,这些字符永远不会相等。
其次,如果要双向绑定SelectedItem,则需要在ConvertBack
方法中放置一些代码(BTW不需要绑定ItemsSource)。