2012-01-24 11 views
0

私はそのような列挙型を持っている: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 
} 

私はコンボボックスにデータソースとしてそれを使用したいと私は表示名を設定する必要があります。 誰でも私を助けることができますか?

答えて

1

それはBLTの契約ではありません...

私の解決策だった:

Test.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); 
     } 
    } 
} 
関連する問題