Silverlight 3 - 从DomainServiceContext绑定枚举到组合框

时间:2009-10-14 18:35:44

标签: silverlight data-binding xaml silverlight-3.0 combobox

我刚刚开始玩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设置?

谢谢,

汤姆

1 个答案:

答案 0 :(得分:2)

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

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

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