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

时间:2012-07-17 22:28:32

标签: c# .net enums encapsulation

相关: Get enum from enum attribute

我希望以最可维护的方式绑定枚举,并将它与关联的本地化字符串值相关联。

如果我把枚举和类放在同一个文件中,我觉得有点安全,但我必须假设有更好的方法。我还考虑过将枚举名称与资源字符串名称相同,但我担心我不能总是在这里强制执行。

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;
        }
    }
}

4 个答案:

答案 0 :(得分:10)

您可以将DescriptionAttribute添加到每个枚举值。

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

在需要时拉出说明(资源键)。

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

编辑:对评论的回应(@Tergiver)。在我的示例中使用(现有)DescriptionAttribute是为了快速完成工作。您最好实现自己的自定义属性,而不是使用其目的之外的属性。像这样:

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

答案 1 :(得分:1)

如果有人没有正确更新,你可能会立即崩溃。

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");
    }
}

答案 2 :(得分:1)

有一种最简单的方法来从资源文件中根据文化获取枚举描述值

我的枚举

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

}

我已将资源文件和密钥与枚举说明值相同

Resoucefile and Enum Key and Value Image, Click to view resouce file 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;
    }

在视图上调用此方法

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

它将使字符串Accedig返回您的文化

答案 3 :(得分:0)

我将在WPF中使用它,这是我实现它的方式

首先,您需要定义属性

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;
        }
    }
}

您可以像这样使用该属性

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

然后定义像

这样的转换器
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;
    }
}

然后在你的XAML中

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

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