简体   繁体   English

将枚举值与本地化字符串资源相链接

[英]Linking enum value with localized string resource

Related: Get enum from enum attribute 相关: 从枚举属性获取枚举

I want the most maintainable way of binding an enumeration and it's associated localized string values to something. 我希望以最可维护的方式绑定枚举,并将它与关联的本地化字符串值相关联。

If I stick the enum and the class in the same file I feel somewhat safe but I have to assume there is a better way. 如果我把枚举和类放在同一个文件中,我觉得有些安全,但我必须假设有更好的方法。 I've also considered having the enum name be the same as the resource string name, but I'm afraid I can't always be here to enforce that. 我还考虑过将enum名称与资源字符串名称相同,但我担心我不能总是在这里强制执行。

using CR = AcmeCorp.Properties.Resources;

public enum SourceFilterOption
{
    LastNumberOccurences,
    LastNumberWeeks,
    DateRange
    // if you add to this you must update FilterOptions.GetString
}

public class FilterOptions
{
    public Dictionary<SourceFilterOption, String> GetEnumWithResourceString()
    {
        var dict = new Dictionary<SourceFilterOption, String>();
        foreach (SourceFilterOption filter in Enum.GetValues(typeof(SourceFilterOption)))
        {
            dict.Add(filter, GetString(filter));
        }
        return dict;
    }

    public String GetString(SourceFilterOption option)
    {
        switch (option)
        {
            case SourceFilterOption.LastNumberOccurences:
                return CR.LAST_NUMBER_OF_OCCURANCES;
            case SourceFilterOption.LastNumberWeeks:
                return CR.LAST_NUMBER_OF_WEEKS;
            case SourceFilterOption.DateRange:
            default:
                return CR.DATE_RANGE;
        }
    }
}

You can add DescriptionAttribute to each enum value. 您可以将DescriptionAttribute添加到每个枚举值。

public enum SourceFilterOption
{
    [Description("LAST_NUMBER_OF_OCCURANCES")]
    LastNumberOccurences,
    ...
}

Pull out the description (resource key) when you need it. 在需要时拉出描述(资源键)。

FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute),     
if (attributes.Length > 0)
{
    return attributes[0].Description;
}
else
{
    return value.ToString();
}

http://geekswithblogs.net/paulwhitblog/archive/2008/03/31/use-the-descriptionattribute-with-an-enum-to-display-status-messages.aspx http://geekswithblogs.net/paulwhitblog/archive/2008/03/31/use-the-descriptionattribute-with-an-enum-to-display-status-messages.aspx

Edit: Response to comments (@Tergiver). 编辑:对评论的回应(@Tergiver)。 Using the (existing) DescriptionAttribute in my example is to get the job done quickly. 在我的示例中使用(现有)DescriptionAttribute是为了快速完成工作。 You would be better implementing your own custom attribute instead of using one outside of its purpose. 您最好实现自己的自定义属性,而不是使用其目的之外的属性。 Something like this: 像这样的东西:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inheritable = false)]
public class EnumResourceKeyAttribute : Attribute
{
 public string ResourceKey { get; set; }
}

You could just crash immediately if someone doesn't update it correctly. 如果有人没有正确更新,您可能会立即崩溃。

public String GetString(SourceFilterOption option)
{
    switch (option)
    {
        case SourceFilterOption.LastNumberOccurences:
            return CR.LAST_NUMBER_OF_OCCURANCES;
        case SourceFilterOption.LastNumberWeeks:
            return CR.LAST_NUMBER_OF_WEEKS;
        case SourceFilterOption.DateRange:
            return CR.DATE_RANGE;
        default:
            throw new Exception("SourceFilterOption " + option + " was not found");
    }
}

I do mapping to resourse in the following way: 1. Define a class StringDescription with ctor getting 2 parameters (type of resourse and it's name) 我通过以下方式映射到资源:1。使用ctor获取2个参数(资源类型及其名称)定义一个StringDescription类

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
class StringDescriptionAttribute : Attribute
{
    private string _name;
    public StringDescriptionAttribute(string name)
    {
        _name = name;
    }

    public StringDescriptionAttribute(Type resourseType, string name)
    {
            _name = new ResourceManager(resourseType).GetString(name);

    }
    public string Name { get { return _name; } }
}
  1. Create a resourse file for either culture (for example WebTexts.resx and Webtexts.ru.resx). 为任一文化创建资源文件(例如WebTexts.resx和Webtexts.ru.resx)。 Let is be colours Red, Green, etc... 让我们的颜色是红色,绿色等......

  2. Define enum: 定义枚举:

    enum Colour{ [StringDescription(typeof(WebTexts),"Red")] Red=1 , [StringDescription(typeof(WebTexts), "Green")] Green = 2, [StringDescription(typeof(WebTexts), "Blue")] Blue = 3, [StringDescription("Antracit with mad dark circles")] AntracitWithMadDarkCircles 枚举颜色{[StringDescription(typeof(WebTexts),“Red”)] Red = 1,[StringDescription(typeof(WebTexts),“Green”)] Green = 2,[StringDescription(typeof(WebTexts),“Blue”)]蓝色= 3,[StringDescription(“Antracit with mad dark circles”)] AntracitWithMadDarkCircles

    } }

  3. Define a static method getting resource description via reflection 定义通过反射获取资源描述的静态方法

    public static string GetStringDescription(Enum en) { public static string GetStringDescription(Enum en){

      var enumValueName = Enum.GetName(en.GetType(),en); FieldInfo fi = en.GetType().GetField(enumValueName); var attr = (StringDescriptionAttribute)fi.GetCustomAttribute(typeof(StringDescriptionAttribute)); return attr != null ? attr.Name : ""; } 
  4. Eat : 吃 :

    Colour col; 颜色col; col = Colour.Red; col = Colour.Red; Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US"); Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(“en-US”);

      var ListOfColors = typeof(Colour).GetEnumValues().Cast<Colour>().Select(p => new { Id = p, Decr = GetStringDescription(p) }).ToList(); foreach (var listentry in ListOfColors) Debug.WriteLine(listentry.Id + " " + listentry.Decr); 

There is the simplest way to getting the enum description value according to culture from resources files 有一种最简单的方法可以根据资源文件中的文化来获取枚举描述值

My Enum 我的枚举

  public enum DiagnosisType
    {
        [Description("Nothing")]
        NOTHING = 0,
        [Description("Advice")]
        ADVICE = 1,
        [Description("Prescription")]
        PRESCRIPTION = 2,
        [Description("Referral")]
        REFERRAL = 3

} }

i have made resource file and key Same as Enum Description Value 我已经使资源文件和密钥与枚举描述值相同

Resoucefile and Enum Key and Value Image, Click to view resouce file image Resoucefile和Enum Key和Value Image,单击查看资源文件图像

   public static string GetEnumDisplayNameValue(Enum enumvalue)
    {
        var name = enumvalue.ToString();
        var culture = Thread.CurrentThread.CurrentUICulture;
        var converted = YourProjectNamespace.Resources.Resource.ResourceManager.GetString(name, culture);
        return converted;
    }

Call this method on view 在视图上调用此方法

  <label class="custom-control-label" for="othercare">YourNameSpace.Yourextenstionclassname.GetEnumDisplayNameValue(EnumHelperClass.DiagnosisType.NOTHING )</label>

It will return the string accordig to your culture 它会将字符串accig返回给您的文化

I've to use it in WPF here is how I achieve it 我要在WPF中使用它,这是我如何实现它

First of all you need to define an attribute 首先,您需要定义一个属性

public class LocalizedDescriptionAttribute : DescriptionAttribute
{
    private readonly string _resourceKey;
    private readonly ResourceManager _resource;
    public LocalizedDescriptionAttribute(string resourceKey, Type resourceType)
    {
        _resource = new ResourceManager(resourceType);
        _resourceKey = resourceKey;
    }

    public override string Description
    {
        get
        {
            string displayName = _resource.GetString(_resourceKey);

            return string.IsNullOrEmpty(displayName)
                ? string.Format("[[{0}]]", _resourceKey)
                : displayName;
        }
    }
}

You can use that attribute like this 您可以像这样使用该属性

public enum OrderType
{
    [LocalizedDescription("DineIn", typeof(Properties.Resources))]
    DineIn = 1,
    [LocalizedDescription("Takeaway", typeof(Properties.Resources))]
    Takeaway = 2
}

Then Define a converter like 然后定义一个转换器

public class EnumToDescriptionConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo language)
    {
        var enumValue = value as Enum;

        return enumValue == null ? DependencyProperty.UnsetValue : enumValue.GetDescriptionFromEnumValue();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language)
    {
        return value;
    }
}

Then in your XAML 然后在你的XAML中

<cr:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter" />

<TextBlock Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM