Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将枚举值与本地化字符串资源链接_C#_.net_Enums_Encapsulation - Fatal编程技术网

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

C# 将枚举值与本地化字符串资源链接,c#,.net,enums,encapsulation,C#,.net,Enums,Encapsulation,相关的: 我想要一种最易于维护的方法来绑定枚举及其关联的本地化字符串值 如果我将枚举和类放在同一个文件中,我会觉得有点安全,但我必须假设有更好的方法。我还考虑过让枚举名与资源字符串名相同,但恐怕我不能总是在这里强制执行 using CR = AcmeCorp.Properties.Resources; public enum SourceFilterOption { LastNumberOccurences, LastNumberWeeks, DateRange

相关的:

我想要一种最易于维护的方法来绑定枚举及其关联的本地化字符串值

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

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;
        }
    }
}
使用CR=AcmeCorp.Properties.Resources;
公共枚举源筛选器选项
{
最近几次治疗,
最近几周,
日期范围
//如果添加到该选项,则必须更新FilterOptions.GetString
}
公共类筛选器选项
{
公共字典GetEnumWithResourceString()
{
var dict=新字典();
foreach(Enum.GetValues中的SourceFilterOption筛选器(typeof(SourceFilterOption)))
{
dict.Add(filter,GetString(filter));
}
返回命令;
}
公共字符串GetString(SourceFilterOption选项)
{
开关(选件)
{
案例来源过滤器选项.LastNumberCurences:
返回上次发生的事件数;
case SourceFilterOption.LastNumberWeeks:
返回CR.LAST\u NUMBER\u周数;
案例SourceFilterOption.DateRange:
违约:
返回CR.DATE\u范围;
}
}
}

您可以向每个枚举值添加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();
}

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

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

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

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

我通过以下方式映射到资源: 1.定义一个类StringDescription,其中包含两个参数(资源类型及其名称)

  • 为任一区域性(例如webtext.resx和webtext.ru.resx)创建资源文件。让我们用红色、绿色等颜色

  • 定义枚举:

    枚举颜色{ [StringDescription(类型为(网络文本),“红色”)] 红色=1, [StringDescription(网络文本的类型),“绿色”)] 绿色=2, [StringDescription(typeof(WebText),“蓝色”)] 蓝色=3, [StringDescription(“带疯狂黑眼圈的Antracit”)] 正反方向圆

    }

  • 定义通过反射获取资源描述的静态方法

    公共静态字符串GetStringDescription(枚举en) {

  • 吃:

    颜色颜色; col=颜色。红色; Thread.CurrentThread.CurrentUICulture=新系统.Globalization.CultureInfo(“en-US”)

    var-ListOfColors=typeof(color).GetEnumValues().Cast().Select(p=>new{Id=p,Decr=GetStringDescription(p)}.ToList();
    foreach(颜色列表中的var listentry)
    Debug.WriteLine(listentry.Id+“”+listentry.Decr);
    

  • 我必须在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}}"/>
    

    根据资源文件中的区域性,有一种获取枚举描述值的最简单方法

    我的枚举

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

    我已使资源文件和密钥与枚举描述值相同

    在视图中调用此方法

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

    它将根据您的区域性返回字符串

    我喜欢这样,尽管我可能会创建一个新属性,如ResourceNameAttribute。我会让它打开一段时间,看看是否有更好的方法,但我已经在更新我的代码了。谢谢,呃,否决票,想解释一下吗?它不起作用吗?因为它比我的解决方案好。+1虽然我也不希望滥用thisUgh的现有属性,但这不适用于我的特定用例(本地化字符串)。当我这样做时:public enum sourcefilter选项{[LocalizedString(CR.LAST_NUMBER_OF u occurrences)]我得到“属性参数必须是常量”。@Joe,在属性中使用常量资源键。属性参数必须是常量。当您在运行时从属性中获取该值时,请将该值用作资源文件的键。您是否绑定到字典?+1表示默认情况下的异常。我讨厌在switch/case语句中看到枚举返回(有效)值的默认情况。这真的可以隐藏错误。。。
    <cr:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter" />
    
    <TextBlock Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}"/>
    
      public enum DiagnosisType
        {
            [Description("Nothing")]
            NOTHING = 0,
            [Description("Advice")]
            ADVICE = 1,
            [Description("Prescription")]
            PRESCRIPTION = 2,
            [Description("Referral")]
            REFERRAL = 3
    
       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>