Comment définir le nom d'affichage sur les champs Enum par blotoolkit?
-
13-11-2019 - |
Question
J'ai un énum comme celui-là:
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
}
Je veux l'utiliser comme source de données dans une combinaison et je dois définir un nom d'affichage. N'importe qui peut m'aider?
La solution
Ce n'est pas l'affaire BLT ...
Ma solution était:
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);
}
}
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow