微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

绑定ComboBoxes到枚举…在Silverlight!

所以,网络和StackOverflow,有很多很好的答案,如何绑定组合框到WPF中的枚举属性。但Silverlight缺少所有的功能,使这可能:(例如:

>您不能使用接受类型参数的通用EnumDisplayer样式IValueConverter,因为Silverlight不支持x:Type。
>您不能使用ObjectDataProvider,如在this approach,因为它不存在于Silverlight中。
>您不能使用自定义标记扩展,如#2中的链接的注释,因为在Silverlight中不存在标记扩展。
>你不能做一个版本的#1使用泛型而不是对象的类型属性,因为XAML不支持泛型(和使它们工作的所有依赖于标记扩展,不支持在Silverlight)。

大规模失败!

正如我看到的,使这项工作的唯一方法

>欺骗并绑定到我的viewmodel中的字符串属性,其setter / getter执行转换,使用代码隐藏在View中将值加载到ComboBox中。
>为要绑定的每个枚举创建一个自定义IValueConverter。

有没有更通用的替代方法,即不涉及为每个我想要的枚举重复编写相同的代码?我想我可以做解决方案#2使用一个类接受枚举作为一个类型参数,然后为我想要的每个枚举创建新类,只是

class MyEnumConverter : GenericEnumConverter<MyEnum> {}

你的想法是什么,伙计们?

解决方法

Agh,我说得太快了!有 a perfectly good solution,至少在Silverlight 3.(它可能只有3,因为 this thread表示与这个东西的一个错误在Silverlight 3中修复)

基本上,你需要一个单一的转换器为ItemsSource属性,但它可以是完全通用的,而不使用任何禁止方法,只要你传递一个类型为MyEnum的属性名称。和SelectedItem的数据绑定是完全无痛的;无需转换器!好吧,至少它只要你不想要自定义字符串为每个枚举值通过例如。 DescriptionAttribute,hmm …可能需要另一个转换器;希望我可以使它泛型。

更新:我做了一个转换器,它的工作原理!我现在必须绑定到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,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,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,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 / etc。新手。例如,EnumToIntConverter.ConvertBack会变慢,那么我应该考虑使用缓存吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐