Создать собственный атрибут DisplayAttribute для перечислений?
У меня есть класс enum...
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
Я видел несколько других тем, которые как бы танцуют вокруг этой проблемы, но контекст настолько отличается, что я не могу заставить его работать. Я предполагаю, что мне нужно создать какой-то класс расширения / переопределения, но я не представляю это в своей голове.
Спасибо!
3 ответа
Имея свой собственный атрибут.
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>();
}
}
}
Теперь вы можете извлечь атрибут из enum следующим образом.
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;
public sealed class DisplayAttribute : Attribute
это закрытый класс, и поэтому вы не можете наследовать его и добавлять к нему другое поведение или свойства.
Ниже мое предположение, но кто-то может вмешаться, если они знают, почему
И вы можете задаться вопросом, почему разработчики.NET сделали это закрытым? Мне интересно то же самое, и я предполагаю, что каждый из свойств в DisplayAttribute
используются для внедрения JavaScript, HTML и т. д. Если они оставили его открытым, и вы добавили BackgroundColor
собственность на это, что это значит? Что это будет делать в пользовательском интерфейсе?
Сделав вывод, что это невозможно, я выбрал другое решение. Не так аккуратно, как я надеялся изначально, но он все еще выполняет свою работу.