2009-10-14 82 views
3

我刚开始玩弄Silverlight和一个简单的东西,比如绑定一个Combobox,这让我疯狂。我现在阅读了大量文章,但没有一篇真正解决了我为Silverlight 2制作或制作的问题,而且似乎没有奏效。Silverlight 3 - 从DomainServiceContext绑定枚举到组合框

比方说,我有一个实体对象“用户”,它有一个“UserStatus”字段。在数据库UserStatus字段定义为字节代码,因为它的定义:

public enum UserStatus : byte 
{ 
    Active = 1, 
    Locked = 2, 
    Suspended = 3, 
} 

当ADO.NET实体框架创建离开UserStatus字段字节的用户实体。因此,要解决这个问题我偶然发现的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 
} 

现在,我还需要提供组合框的的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”或“Active”,它们都不起作用。 任何人都可以帮助我,告诉我什么是错的,为什么我似乎无法得到SelectedItem集?

感谢,

汤姆

回答

2

我可以看到两个问题与您的代码。

首先,在silverlight 3中,ComboBox通过object.Equals方法将SelectedItem中的对象与ItemsSource中的对象集相匹配。然而你的GetValues方法返回一个Boxed枚举值的数组。而你的EnumConverter返回一个字符串。因此,你要求Silverlight比较一个字节和一个字符串,这些永远不会相等。

其次,如果您要双向绑定SelectedItem(顺便说一句,不需要双向绑定ItemsSource),您需要在ConvertBack方法中放置一些代码。

+0

杜哈,你当然很对,谢谢安东尼。只需调用f.GetValue(null).ToString()修复它。 Btw。 thx我知道未实现的用于双向绑定的ConvertBack,只是希望首先获得绑定的第一部分:) – TJF 2009-10-15 13:20:22