【问题标题】:Create a custom DisplayAttribute for enums?为枚举创建自定义 DisplayAttribute?
【发布时间】:2017-05-07 11:05:22
【问题描述】:

我有一个枚举类...

public enum LeadStatus : byte
{
    [Display(Name = "Created")] Created = 1,
    [Display(Name = "Assigned")] Assigned = 2,
    ....
}

Name 当然是开箱即用的。来自元数据...

namespace System.ComponentModel.DataAnnotations
{
    public sealed class DisplayAttribute : Attribute
    {
        ...
        public string Name { get; set; }
        ...
    }
}

假设我想要自己的自定义显示属性,例如“BackgroundColor”...

[Display(Name = "Created", BackgroundColor="green")] Created = 1

我在这里看到了一些其他的主题,这些主题有点绕着这个问题跳舞,但上下文不同,我无法让它发挥作用。我假设我需要创建某种扩展/覆盖类,但我并没有在脑海中想象这一点。

谢谢!

【问题讨论】:

  • 创建属性很容易。只需从 Attribute 继承您的自定义类。稍后您可以从枚举成员中提取属性信息。
  • 原谅我...但是“简单”对不同的人可能意味着不同的事情!
  • 嘿,请再看一下答案并复制粘贴。它会起作用的。请注意名称空间很重要,因为您想隐藏原始的 DisplayAttribute 并使用您自己的。
  • 好的,我在找。谢谢你的帮助!!

标签: c# asp.net enums displayattribute


【解决方案1】:

拥有自己的属性。

public sealed class ExtrasDisplayAttribute : Attribute
{
    public string Name { get; set; }
    public string BackgroundColor { get; set; }
}

还有这个扩展方法。

namespace ExtensionsNamespace
{
    public static class Extensions
    {
        public static TAttribute GetAttribute<TAttribute>(Enum value) where TAttribute : Attribute
        {
            return value.GetType()
                .GetMember(value.ToString())[0]
                .GetCustomAttribute<TAttribute>();
        }
    }
}

现在你可以像这样从枚举中提取属性了。

using static ExtensionsNamespace.Extensions;

//...

var info = GetAttribute<ExtrasDisplayAttribute>(LeadStatus.Created);
var name = info.Name;
var bg = info.BackgroundColor;

//...

public enum LeadStatus : byte
{
    [ExtrasDisplay(Name = "Created", BackgroundColor = "Red")] Created = 1,
    [ExtrasDisplay(Name = "Assigned")] Assigned = 2,
}

如果您仍想使用原始属性,您也可以使用它。 您应该将这两个属性应用于单个枚举。

public enum LeadStatus : byte
{
    [Display(Name = "Created"), ExtrasDisplay(BackgroundColor = "Red")]Created = 1,
    [Display(Name = "Assigned")] Assigned = 2,
}

然后提取你想要的每一个。

var name = GetAttribute<DisplayAttribute>(LeadStatus.Created).Name;
var bg = GetAttribute<ExtrasDisplayAttribute>(LeadStatus.Created).BackgroundColor;

【讨论】:

  • 这里有些麻烦.... BackgroundColor 无法识别。 “找不到类型或命名空间 BackgroundColor。”我在尝试将它用作枚举属性中的显示属性时得到了这一点
  • 在我的代码/项目中,我应该将扩展方法放在您的第二个代码块中的什么位置?
  • 我在这里遗漏了一些东西。在实际的 *.cs 文件中......我应该将这两个类放在与 enum 类相同的文字文件中吗?还是只需要在同一个命名空间中?
  • 此解决方案不起作用。这不是像 OP 要求的那样将 BackgroundColor 添加到 DisplayAttribute 类中。
  • @M.kazemAkhgary -- 我要感谢您的努力!我确实让您的解决方案起作用,但我也可以看到 CodingYoshi 有一个有效的观点。不使用 MVC 的类会导致更多的麻烦。话虽如此,我确实很感谢您的时间和精力。我对此投了赞成票。
【解决方案2】:

public sealed class DisplayAttribute : Attribute 是一个密封类,因此您不能继承它并向其添加其他行为或属性。

以下是我的假设,但如果有人知道原因,可以插话

您可能想知道为什么 .NET 开发人员将其密封?我想知道同样的问题,我的假设是因为DisplayAttribute 中的每个属性都用于注入 javascript、html 等。如果它们将其保持打开状态,并且您向其添加了 BackgroundColor 属性,那是什么意思?这会在 UI 中做什么?

【讨论】:

  • 那么,你是说这不可能吗?如果是这样,是否有某种解决方法?
  • 不需要继承或覆盖这个属性。只需您可以编写自己的属性。我的回答会很好。
  • 只有我没有让它工作。正如我在您的回答下的评论中所说,“BackgroundColor”无法识别。
  • @CaseyCrookston 我想也许如果你将整个DisplayAttribute 包装在一个类中,该类实现一个具有DisplayAttribute 的所有方法和属性的接口,然后使用装饰器模式......但是然后我想当你在你的 UI 中使用它时,它不会起作用,所以我放弃了娱乐。很抱歉,我什么都想不出来,但如果我想出什么,我一定会联系你的。
  • 好的。所以最后的解决方法是将两个属性应用于每个成员。这可能像[FistAttribute(...) , SecondAttrbute(...)] 一样,然后提取你想要的那个。 @CaseyCrookston
【解决方案3】:

得出结论这是不可能的,我选择了另一种解决方案。不像我最初希望的那样整洁,但它仍然可以完成工作。

Methods inside enum in C#

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-11
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    相关资源
    最近更新 更多