如何通过BLToolkit设置枚举字段的显示名称



我有一个类似的枚举:

public enum Mode
{
[*"I need a display name attribute to show in combobox"*]
Active,
[*"I need a display name attribute to show in combobox"*]
DeActive
}

我想把它用作comboBox中的dataSource,我需要设置显示名称。有人能帮我吗?

这不是BLT交易。。。

我的解决方案是:

测试.cs

using System;
using DK.Common.Caption;
using NUnit.Framework;
namespace DK.Common.Tests
{
    [TestFixture]
    public class LocalizedEnumConverterTests
    {
        const string FirstName = "Первый";
        const string FirstResName = "TestEnumFirst";
        const string SecondName = "Второй";
        const string SecondResName = "SecondResName";
        const string ThirdName = "Третий";
        const string FourthName = "Fourth";
        const string EmptyName = "This is empty!";
        [Flags]
        enum TestEnum
        {
            [Caption(FirstName)] 
            First = 1,
            [Caption(SecondName, SecondResName)] 
            Second = 2,
            [Caption(ThirdName)] 
            Third = 4,
            Fourth = 8,
            [Caption] 
            Empty = 16,
        }
        readonly LocalizedEnumConverter _converter = new LocalizedEnumConverter(typeof (TestEnum));
        [Test]
        public void ToStringTest()
        {
            Func<TestEnum, string> c = (e) => _converter.ConvertToString(null, e);
            Assert.AreEqual(FirstResName, c(TestEnum.First));
            Assert.AreEqual(SecondResName, c(TestEnum.Second));
            Assert.AreEqual(ThirdName, c(TestEnum.Third));
            Assert.AreEqual(EmptyName, c(TestEnum.Empty));
            Assert.AreEqual(SecondResName + ", " + FourthName, c(TestEnum.Second | TestEnum.Fourth));
        }
        [Test]
        public void FromStringTest()
        {
            Func<string, TestEnum> c = (s) => (TestEnum) _converter.ConvertFromString(null, s);
            Assert.AreEqual(TestEnum.First, c(FirstResName));
            Assert.AreEqual(TestEnum.Second, c(SecondResName));
            Assert.AreEqual(TestEnum.Third, c(ThirdName));
            Assert.AreEqual(TestEnum.Empty, c(EmptyName));
            Assert.AreEqual(TestEnum.Second | TestEnum.Fourth, c(SecondResName + ", " + FourthName));
        }
        [Test]
        public void FromToTest()
        {
            const TestEnum @enum = TestEnum.First | TestEnum.Second | TestEnum.Third | TestEnum.Fourth | TestEnum.Empty;
            var str = LocalizedEnumConverter.EnumToString(@enum);
            var en = LocalizedEnumConverter.StringToEnum<TestEnum>(str);
            Assert.AreEqual(@enum, en);
        }
    }
}

Caption.cs

using System;

namespace DK.Common.Caption
{
    public class CaptionAttribute : Attribute
    {
        readonly string _caption;
        public CaptionAttribute()
            :this(string.Empty)
        {
        }
        public CaptionAttribute(string caption)
            :this(caption, string.Empty)
        {
        }
        public CaptionAttribute(string caption, string resourceName)
        {
            _caption = caption;
            ResourceName = resourceName;
        }
        public string Caption { get { return _caption; } }
        public string ResourceName { get; private set; }
    }
}

LocalizedEnumConverter.cs

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Resources;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
namespace DK.Common.Caption
{
    using Names = Dictionary<object, string>;
    using Cultures = Dictionary<CultureInfo, Dictionary<object, string>>;
    public class LocalizedEnumConverter : EnumConverter
    {
private int Dummy(int myI)
{
   int i = 10;
   int j = 5;
   return myI+i*j;
}       public LocalizedEnumConverter(Type type) : base(type)
        {
        }
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            Type type = this.EnumType;
            bool isFlags = type.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
            if (destinationType == typeof(string))
            {
                string s = "";
                foreach (object val in Enum.GetValues(type))
                {
                    if ((((int)value & (int)val) != 0 && isFlags)
                        || ((int)value == 0 && (int)val == 0)
                        || Enum.Equals(value, val))
                    {
                        CaptionAttribute[] atr = (CaptionAttribute[])(type.GetField(Enum.GetName(type, val))).GetCustomAttributes(typeof(CaptionAttribute), true);
                        if (atr.Length > 0)
                            s += ", " + GetNames(EnumType, culture)[val];
                        else
                            s += ", " + base.ConvertTo(context, culture, val, destinationType);
                    }
                }
                if (s != "") return s.Substring(2);
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value.GetType() == typeof(string))
            {
                string       caption  = (string)value;
                List<string> splitted = new List<string>(caption.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries));
                //FieldInfo[]  fields   = EnumType.GetFields();
                string       mapped   = "";
                //foreach (FieldInfo fi in fields)
                //{
                //    CaptionAttribute[] atr = (CaptionAttribute[])fi.GetCustomAttributes(typeof(CaptionAttribute), true);
                //    if (atr.Length > 0 && splitted.IndexOf(GetLocalizedCaption(atr[0], value, culture)) >= 0)
                //        mapped += "," + fi.Name;
                //}
                var names = GetNames(EnumType, culture);
                foreach (var val in splitted)
                {
                    foreach (var name in names)
                    {
                        if(name.Value == val)
                        {
                            mapped += "," + name.Key.ToString();
                            break;
                        }
                    }
                }
                if (mapped.Length > 0)
                {
                    object o = base.ConvertFrom(context, culture, mapped.Substring(1)/*fi.Name*/);
                    return o;
                }
            }
            return base.ConvertFrom(context, culture, value);
        }
        private static string GetLocalizedCaption(Type type, CaptionAttribute attr, object val, System.Globalization.CultureInfo culture)
        {
            var resName = attr.ResourceName;
            if (string.IsNullOrEmpty(resName))
            {
                resName = type.Name + val.ToString();
            }
            var m = GetResourceManager(type);
            try
            {
                var caption = m != null ? m.GetString(resName, culture) : string.Empty;
                return string.IsNullOrEmpty(caption) ? attr.Caption : caption;
            }
            catch
            {
                return attr.Caption;
            }
        }
        private static readonly Dictionary<Assembly, ResourceManager> _managers = new Dictionary<Assembly, ResourceManager>();
        private static  readonly Dictionary<Type, Cultures> _names = new Dictionary<Type, Cultures>();
        private static Names GetNames(Type type, CultureInfo cultureInfo)
        {
            lock (_names)
            {
                Cultures cult;
                if(!_names.TryGetValue(type, out cult))
                {
                    _names[type] = new Cultures();
                    cult = _names[type];
                }
                Names n;
                if (cultureInfo == null)
                    cultureInfo = Thread.CurrentThread.CurrentCulture;
                if(!cult.TryGetValue(cultureInfo, out n))
                {
                    n = new Names();
                    foreach (object val in Enum.GetValues(type))
                    {
                        CaptionAttribute[] atr = (CaptionAttribute[])(type.GetField(Enum.GetName(type, val))).GetCustomAttributes(typeof(CaptionAttribute), true);
                        string cap;
                        if (atr.Length > 0)
                            cap = GetLocalizedCaption(type, atr[0], val, cultureInfo);
                        else
                            cap = val.ToString();
                        n[val] = cap;
                    }
                    cult[cultureInfo] = n;
                }
                return n;
            }
        }
        private static ResourceManager GetResourceManager(Type type)
        {
            ResourceManager res;
            if (_managers.TryGetValue(type.Assembly, out res))
                return res;
            lock (_managers)
            {
                if (_managers.TryGetValue(type.Assembly, out res))
                    return res;
                var names = type.Assembly.GetManifestResourceNames();
                // вот только имя сборки и ее ресурсов это вопрос левый... решает не имя сборки, а неймспейс
                //var assemblyName = type.Assembly.GetName().Name;
                //var resName = assemblyName + "Properties.Resources.resources";
                foreach (var name in names)
                {
                    if (/*name.StartsWith(assemblyName, StringComparison.InvariantCultureIgnoreCase)
                        ||*/ name.EndsWith("Properties.Resources.resources", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var n = name.Replace(".resources", "");
                        res = new ResourceManager(n, type.Assembly);
                        break;
                    }
                }
                _managers[type.Assembly] = res;
            }
            return res;
        }
        public static string EnumToString(object from)
        {
            LocalizedEnumConverter conv = new LocalizedEnumConverter(from.GetType());
            return (string)conv.ConvertTo(from, typeof(string));
        }
        public static T StringToEnum<T>(string value)
        {
            var conv = new LocalizedEnumConverter(typeof (T));
            return (T) conv.ConvertFromString(null, value);
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新