Di posting Enum ToString , metode dijelaskan untuk menggunakan atribut khusus DescriptionAttribute
seperti ini:
Enum HowNice {
[Description("Really Nice")]
ReallyNice,
[Description("Kinda Nice")]
SortOfNice,
[Description("Not Nice At All")]
NotNice
}
Dan kemudian, Anda memanggil suatu fungsi GetDescription
, menggunakan sintaks seperti:
GetDescription<HowNice>(NotNice); // Returns "Not Nice At All"
Tetapi itu tidak benar-benar membantu saya ketika saya hanya ingin mengisi ComboBox dengan nilai enum, karena saya tidak bisa memaksa ComboBox untuk memanggilGetDescription
.
Yang saya inginkan memiliki persyaratan berikut:
- Membaca
(HowNice)myComboBox.selectedItem
akan mengembalikan nilai yang dipilih sebagai nilai enum. - Pengguna harus melihat string tampilan yang mudah digunakan, dan bukan hanya nama nilai pencacahan. Jadi, alih-alih melihat "
NotNice
", pengguna akan melihat "Not Nice At All
". - Mudah-mudahan, solusinya membutuhkan sedikit perubahan kode pada pencacahan yang ada.
Jelas, saya bisa mengimplementasikan kelas baru untuk setiap enum yang saya buat, dan menimpanya ToString()
, tapi itu banyak pekerjaan untuk setiap enum, dan saya lebih suka menghindarinya.
Ada ide?
Heck, saya bahkan akan memeluk sebagai hadiah :-)
Jawaban:
Anda bisa menulis TypeConverter yang membaca atribut tertentu untuk mencarinya di resource Anda. Dengan demikian Anda akan mendapatkan dukungan multi-bahasa untuk nama tampilan tanpa banyak kerumitan.
Lihat ke dalam metode ConvertFrom / ConvertTo TypeConverter, dan gunakan refleksi untuk membaca atribut di bidang enum Anda .
sumber
ComboBox
memiliki semua yang Anda butuhkan:FormattingEnabled
properti, yang harus Anda seteltrue
, danFormat
event, di mana Anda perlu menempatkan logika pemformatan yang diinginkan. Jadi,myComboBox.FormattingEnabled = true; myComboBox.Format += delegate(object sender, ListControlConvertEventArgs e) { e.Value = GetDescription<HowNice>((HowNice)e.Value); }
sumber
DataGridComboBoxColumn
. Ada kesempatan untuk menyelesaikannya? Saya tidak bisa menemukan cara untuk mendapatkan akses keComboBox
satuDataGridComboBoxColumn
.Jangan! Enum adalah primitif dan bukan objek UI - membuatnya melayani UI dalam .ToString () akan sangat buruk dari sudut pandang desain. Anda mencoba menyelesaikan masalah yang salah di sini: masalah sebenarnya adalah Anda tidak ingin Enum.ToString () muncul di kotak kombo!
Sekarang ini adalah masalah yang sangat bisa dipecahkan! Anda membuat objek UI untuk mewakili item kotak kombo Anda:
sealed class NicenessComboBoxItem { public string Description { get { return ...; } } public HowNice Value { get; private set; } public NicenessComboBoxItem(HowNice howNice) { Value = howNice; } }
Dan kemudian tambahkan saja contoh kelas ini ke koleksi Item kotak kombo Anda dan setel properti ini:
comboBox.ValueMember = "Value"; comboBox.DisplayMember = "Description";
sumber
Dictionary
dan menggunakan propertiKey
danValue
sebagaiDisplayMember
danValueMember
.TypeConverter. Saya rasa inilah yang saya cari. Salam Simon Svensson !
[TypeConverter(typeof(EnumToStringUsingDescription))] Enum HowNice { [Description("Really Nice")] ReallyNice, [Description("Kinda Nice")] SortOfNice, [Description("Not Nice At All")] NotNice }
Yang perlu saya ubah dalam enum saya saat ini adalah menambahkan baris ini sebelum deklarasi mereka.
[TypeConverter(typeof(EnumToStringUsingDescription))]
Setelah saya melakukannya, enum apa pun akan ditampilkan menggunakan
DescriptionAttribute
bidangnya.Oh, dan
TypeConverter
akan didefinisikan seperti ini:public class EnumToStringUsingDescription : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return (sourceType.Equals(typeof(Enum))); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return (destinationType.Equals(typeof(String))); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (!destinationType.Equals(typeof(String))) { throw new ArgumentException("Can only convert to string.", "destinationType"); } if (!value.GetType().BaseType.Equals(typeof(Enum))) { throw new ArgumentException("Can only convert an instance of enum.", "value"); } string name = value.ToString(); object[] attrs = value.GetType().GetField(name).GetCustomAttributes(typeof(DescriptionAttribute), false); return (attrs.Length > 0) ? ((DescriptionAttribute)attrs[0]).Description : name; } }
Ini membantu saya dengan kasus ComboBox saya, tetapi jelas tidak benar-benar menimpa
ToString()
. Saya kira saya akan menerima ini sementara ...sumber
[TypeConverter(typeof(EnumToStringUsingDescription))] public enum MyEnum {[Description("Blah")] One}
, mencoba melakukanConsole.WriteLine(MyEnum.One)
dan masih keluar sebagai "Satu". Apakah Anda memerlukan sihir khusus sepertiTypeDescriptor.GetConverter(typeof(MyEnum)).ConvertToString(MyEnum.One)
(yang berfungsi dengan baik)?Menggunakan contoh pencacahan Anda:
using System.ComponentModel; Enum HowNice { [Description("Really Nice")] ReallyNice, [Description("Kinda Nice")] SortOfNice, [Description("Not Nice At All")] NotNice }
Buat Ekstensi:
public static class EnumExtensions { public static string Description(this Enum value) { var enumType = value.GetType(); var field = enumType.GetField(value.ToString()); var attributes = field.GetCustomAttributes(typeof(DescriptionAttribute), false); return attributes.Length == 0 ? value.ToString() : ((DescriptionAttribute)attributes[0]).Description; } }
Kemudian Anda dapat menggunakan sesuatu seperti berikut:
HowNice myEnum = HowNice.ReallyNice; string myDesc = myEnum.Description();
Lihat: http://www.blackwasp.co.uk/EnumDescription.aspx untuk informasi lebih lanjut. Penghargaan diberikan kepada Richrd Carr untuk solusinya
sumber
Anda bisa membuat struct generik yang bisa Anda gunakan untuk semua enum yang memiliki deskripsi. Dengan konversi implisit ke dan dari kelas, variabel Anda masih berfungsi seperti enum kecuali untuk metode ToString:
public struct Described<T> where T : struct { private T _value; public Described(T value) { _value = value; } public override string ToString() { string text = _value.ToString(); object[] attr = typeof(T).GetField(text) .GetCustomAttributes(typeof(DescriptionAttribute), false); if (attr.Length == 1) { text = ((DescriptionAttribute)attr[0]).Description; } return text; } public static implicit operator Described<T>(T value) { return new Described<T>(value); } public static implicit operator T(Described<T> value) { return value._value; } }
Contoh penggunaan:
Described<HowNice> nice = HowNice.ReallyNice; Console.WriteLine(nice == HowNice.ReallyNice); // writes "True" Console.WriteLine(nice); // writes "Really Nice"
sumber
Saya tidak berpikir Anda dapat melakukannya tanpa hanya mengikat jenis yang berbeda - setidaknya, tidak nyaman. Biasanya, bahkan jika Anda tidak dapat mengontrol
ToString()
, Anda dapat menggunakanTypeConverter
untuk melakukan pemformatan khusus - tetapi IIRCSystem.ComponentModel
barang - barang tersebut tidak menghormati ini untuk enum.Anda bisa mengikat ke salah
string[]
satu deskripsi, atau sesuatu yang pada dasarnya seperti pasangan kunci / nilai? (deskripsi / nilai) - sesuatu seperti:class EnumWrapper<T> where T : struct { private readonly T value; public T Value { get { return value; } } public EnumWrapper(T value) { this.value = value; } public string Description { get { return GetDescription<T>(value); } } public override string ToString() { return Description; } public static EnumWrapper<T>[] GetValues() { T[] vals = (T[])Enum.GetValues(typeof(T)); return Array.ConvertAll(vals, v => new EnumWrapper<T>(v)); } }
Dan kemudian mengikat ke
EnumWrapper<HowNice>.GetValues()
sumber
theComboBox.SelectItem
adalah tipeEnumWrapper<T>
, bukanT
dirinya sendiri. Saya pikir scraimer inginReading (HowNice)myComboBox.selectedItem will return the selected value as the enum value.
.Cara terbaik untuk melakukannya adalah dengan membuat kelas.
class EnumWithToString { private string description; internal EnumWithToString(string desc){ description = desc; } public override string ToString(){ return description; } } class HowNice : EnumWithToString { private HowNice(string desc) : base(desc){} public static readonly HowNice ReallyNice = new HowNice("Really Nice"); public static readonly HowNice KindaNice = new HowNice("Kinda Nice"); public static readonly HowNice NotVeryNice = new HowNice("Really Mean!"); }
Saya yakin itulah cara terbaik untuk melakukannya.
Ketika dimasukkan ke dalam kotak kombo, ToString cantik akan ditampilkan, dan fakta bahwa tidak ada lagi yang dapat membuat contoh kelas Anda lagi pada dasarnya menjadikannya enum.
ps mungkin perlu ada sedikit perbaikan sintaks, saya tidak terlalu baik dengan C #. (Orang Jawa)
sumber
private HowNice(String desc) : base(desc) { }
dan bidang statis.Mengingat bahwa Anda lebih suka tidak membuat kelas untuk setiap enum, saya sarankan membuat kamus teks nilai / tampilan enum dan mengikatnya sebagai gantinya.
Perhatikan bahwa ini memiliki ketergantungan pada metode metode GetDescription di postingan asli.
public static IDictionary<T, string> GetDescriptions<T>() where T : struct { IDictionary<T, string> values = new Dictionary<T, string>(); Type type = enumerationValue.GetType(); if (!type.IsEnum) { throw new ArgumentException("T must be of Enum type", "enumerationValue"); } //Tries to find a DescriptionAttribute for a potential friendly name //for the enum foreach (T value in Enum.GetValues(typeof(T))) { string text = value.GetDescription(); values.Add(value, text); } return values; }
sumber
Tidak mungkin untuk menimpa ToString () dari enum di C #. Namun, Anda dapat menggunakan metode ekstensi;
public static string ToString(this HowNice self, int neverUsed) { switch (self) { case HowNice.ReallyNice: return "Rilly, rilly nice"; break; ...
Tentu saja Anda harus membuat panggilan eksplisit ke metode tersebut, yaitu;
HowNice.ReallyNice.ToString(0)
Ini bukan solusi yang bagus, dengan pernyataan sakelar dan semuanya - tetapi itu harus berfungsi dan mudah-mudahan memutihkan banyak penulisan ulang ...
sumber
Menindaklanjuti jawaban @scraimer, berikut adalah versi konverter tipe enum-ke-string, yang juga mendukung flag:
/// <summary> /// A drop-in converter that returns the strings from /// <see cref="System.ComponentModel.DescriptionAttribute"/> /// of items in an enumaration when they are converted to a string, /// like in ToString(). /// </summary> public class EnumToStringUsingDescription : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return (sourceType.Equals(typeof(Enum))); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return (destinationType.Equals(typeof(String))); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (destinationType.Equals(typeof(String))) { string name = value.ToString(); Type effectiveType = value.GetType(); if (name != null) { FieldInfo fi = effectiveType.GetField(name); if (fi != null) { object[] attrs = fi.GetCustomAttributes(typeof(DescriptionAttribute), false); return (attrs.Length > 0) ? ((DescriptionAttribute)attrs[0]).Description : name; } } } return base.ConvertTo(context, culture, value, destinationType); } /// <summary> /// Coverts an Enums to string by it's description. falls back to ToString. /// </summary> /// <param name="value">The value.</param> /// <returns></returns> public string EnumToString(Enum value) { //getting the actual values List<Enum> values = EnumToStringUsingDescription.GetFlaggedValues(value); //values.ToString(); //Will hold results for each value List<string> results = new List<string>(); //getting the representing strings foreach (Enum currValue in values) { string currresult = this.ConvertTo(null, null, currValue, typeof(String)).ToString();; results.Add(currresult); } return String.Join("\n",results); } /// <summary> /// All of the values of enumeration that are represented by specified value. /// If it is not a flag, the value will be the only value retured /// </summary> /// <param name="value">The value.</param> /// <returns></returns> private static List<Enum> GetFlaggedValues(Enum value) { //checking if this string is a flaged Enum Type enumType = value.GetType(); object[] attributes = enumType.GetCustomAttributes(true); bool hasFlags = false; foreach (object currAttibute in attributes) { if (enumType.GetCustomAttributes(true)[0] is System.FlagsAttribute) { hasFlags = true; break; } } //If it is a flag, add all fllaged values List<Enum> values = new List<Enum>(); if (hasFlags) { Array allValues = Enum.GetValues(enumType); foreach (Enum currValue in allValues) { if (value.HasFlag(currValue)) { values.Add(currValue); } } } else//if not just add current value { values.Add(value); } return values; } }
Dan metode ekstensi untuk menggunakannya:
/// <summary> /// Converts an Enum to string by it's description. falls back to ToString /// </summary> /// <param name="enumVal">The enum val.</param> /// <returns></returns> public static string ToStringByDescription(this Enum enumVal) { EnumToStringUsingDescription inter = new EnumToStringUsingDescription(); string str = inter.EnumToString(enumVal); return str; }
sumber
Saya akan menulis kelas generik untuk digunakan dengan jenis apa pun. Saya pernah menggunakan sesuatu seperti ini di masa lalu:
public class ComboBoxItem<T> { /// The text to display. private string text = ""; /// The associated tag. private T tag = default(T); public string Text { get { return text; } } public T Tag { get { return tag; } } public override string ToString() { return text; } // Add various constructors here to fit your needs }
Di atas ini, Anda dapat menambahkan "metode pabrik" statis untuk membuat daftar item kotak kombo yang diberi jenis enum (hampir sama dengan metode GetDescriptions yang Anda miliki di sana). Ini akan menyelamatkan Anda dari keharusan untuk mengimplementasikan satu entitas per setiap jenis enum, dan juga menyediakan tempat yang bagus / logis untuk metode pembantu "GetDescriptions" (secara pribadi saya akan menyebutnya FromEnum (T obj) ...
sumber
Buat koleksi yang berisi apa yang Anda butuhkan (seperti objek sederhana yang berisi
Value
properti yang berisi nilaiHowNice
enum danDescription
properti yang berisiGetDescription<HowNice>(Value)
dan databind combo ke koleksi itu.Sedikit seperti ini:
Combo.DataSource = new EnumeratedValueCollection<HowNice>(); Combo.ValueMember = "Value"; Combo.DisplayMember = "Description";
ketika Anda memiliki kelas koleksi seperti ini:
using System; using System.Linq; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Whatever.Tickles.Your.Fancy { public class EnumeratedValueCollection<T> : ReadOnlyCollection<EnumeratedValue<T>> { public EnumeratedValueCollection() : base(ListConstructor()) { } public EnumeratedValueCollection(Func<T, bool> selection) : base(ListConstructor(selection)) { } public EnumeratedValueCollection(Func<T, string> format) : base(ListConstructor(format)) { } public EnumeratedValueCollection(Func<T, bool> selection, Func<T, string> format) : base(ListConstructor(selection, format)) { } internal EnumeratedValueCollection(IList<EnumeratedValue<T>> data) : base(data) { } internal static List<EnumeratedValue<T>> ListConstructor() { return ListConstructor(null, null); } internal static List<EnumeratedValue<T>> ListConstructor(Func<T, string> format) { return ListConstructor(null, format); } internal static List<EnumeratedValue<T>> ListConstructor(Func<T, bool> selection) { return ListConstructor(selection, null); } internal static List<EnumeratedValue<T>> ListConstructor(Func<T, bool> selection, Func<T, string> format) { if (null == selection) selection = (x => true); if (null == format) format = (x => GetDescription<T>(x)); var result = new List<EnumeratedValue<T>>(); foreach (T value in System.Enum.GetValues(typeof(T))) { if (selection(value)) { string description = format(value); result.Add(new EnumeratedValue<T>(value, description)); } } return result; } public bool Contains(T value) { return (Items.FirstOrDefault(item => item.Value.Equals(value)) != null); } public EnumeratedValue<T> this[T value] { get { return Items.First(item => item.Value.Equals(value)); } } public string Describe(T value) { return this[value].Description; } } [System.Diagnostics.DebuggerDisplay("{Value} ({Description})")] public class EnumeratedValue<T> { private T value; private string description; internal EnumeratedValue(T value, string description) { this.value = value; this.description = description; } public T Value { get { return this.value; } } public string Description { get { return this.description; } } } }
Seperti yang Anda lihat, koleksi ini mudah disesuaikan dengan lambda's untuk memilih subset dari enumerator Anda dan / atau menerapkan pemformatan kustom
string
daripada menggunakanGetDescription<T>(x)
fungsi yang Anda sebutkan.sumber
Anda dapat menggunakan PostSharp untuk menargetkan Enum.ToString dan menambahkan semua kode yang Anda inginkan. Ini tidak memerlukan perubahan kode apa pun.
sumber
Yang Anda butuhkan adalah mengubah enum menjadi ReadonlyCollection dan mengikat koleksi ke kotak kombo (atau kontrol yang mengaktifkan Key-Value Pair dalam hal ini)
Pertama, Anda memerlukan kelas untuk memuat item dari daftar. Karena yang Anda butuhkan hanyalah pasangan int / string yang saya sarankan menggunakan antarmuka dan kombinasi kelas dasar sehingga Anda dapat menerapkan fungsionalitas di objek apa pun yang Anda inginkan:
public interface IValueDescritionItem { int Value { get; set;} string Description { get; set;} } public class MyItem : IValueDescritionItem { HowNice _howNice; string _description; public MyItem() { } public MyItem(HowNice howNice, string howNice_descr) { _howNice = howNice; _description = howNice_descr; } public HowNice Niceness { get { return _howNice; } } public String NicenessDescription { get { return _description; } } #region IValueDescritionItem Members int IValueDescritionItem.Value { get { return (int)_howNice; } set { _howNice = (HowNice)value; } } string IValueDescritionItem.Description { get { return _description; } set { _description = value; } } #endregion }
Berikut adalah antarmuka dan contoh kelas yang mengimplementasikannya Perhatikan bahwa kelas 'Key diketik dengan kuat ke Enum, dan bahwa properti IValueDescritionItem diimplementasikan secara eksplisit (sehingga kelas dapat memiliki properti apa pun dan Anda dapat MEMILIH properti yang mengimplementasikan Pasangan Kunci / Nilai.
Sekarang kelas EnumToReadOnlyCollection:
public class EnumToReadOnlyCollection<T,TEnum> : ReadOnlyCollection<T> where T: IValueDescritionItem,new() where TEnum : struct { Type _type; public EnumToReadOnlyCollection() : base(new List<T>()) { _type = typeof(TEnum); if (_type.IsEnum) { FieldInfo[] fields = _type.GetFields(); foreach (FieldInfo enum_item in fields) { if (!enum_item.IsSpecialName) { T item = new T(); item.Value = (int)enum_item.GetValue(null); item.Description = ((ItemDescription)enum_item.GetCustomAttributes(false)[0]).Description; //above line should be replaced with proper code that gets the description attribute Items.Add(item); } } } else throw new Exception("Only enum types are supported."); } public T this[TEnum key] { get { return Items[Convert.ToInt32(key)]; } } }
Jadi yang Anda butuhkan dalam kode Anda adalah:
private EnumToReadOnlyCollection<MyItem, HowNice> enumcol; enumcol = new EnumToReadOnlyCollection<MyItem, HowNice>(); comboBox1.ValueMember = "Niceness"; comboBox1.DisplayMember = "NicenessDescription"; comboBox1.DataSource = enumcol;
Ingat bahwa koleksi Anda diketik dengan MyItem sehingga nilai kotak kombo harus mengembalikan nilai enum jika Anda mengikat ke properti yang sesuai.
Saya menambahkan properti T this [Enum t] untuk membuat koleksi lebih berguna daripada combo yang dapat dikonsumsi, misalnya textBox1.Text = enumcol [HowNice.ReallyNice] .NicenessDescription;
Anda tentu saja dapat memilih untuk mengubah MyItem menjadi kelas Key / Value yang digunakan hanya untuk puprose ini secara efektif melewatkan MyItem dalam argumen tipe EnumToReadnlyCollection sama sekali, tetapi kemudian Anda akan dipaksa untuk menggunakan int untuk kunci (artinya mendapatkan combobox1.SelectedValue akan mengembalikan int dan bukan tipe enum). Anda mengatasinya jika Anda membuat kelas KeyValueItem untuk menggantikan MyItem dan seterusnya dan seterusnya ...
sumber
Maaf untuk menyelesaikan utas lama ini.
Saya akan melakukan cara berikut untuk melokalkan enum, karena dapat menampilkan nilai yang bermakna dan dilokalkan kepada pengguna, bukan hanya deskripsi, melalui bidang teks daftar turun-bawah dalam contoh ini.
Pertama, saya membuat metode sederhana yang disebut OwToStringByCulture untuk mendapatkan string yang dilokalkan dari file sumber daya global, dalam contoh ini adalah BiBongNet.resx di folder App_GlobalResources. Di dalam file sumber daya ini, pastikan Anda memiliki semua string yang sama dengan nilai enum (ReallyNice, SortOfNice, NotNice). Dalam metode ini, saya meneruskan parameter: resourceClassName yang biasanya merupakan nama file resource.
Selanjutnya, saya membuat metode statis untuk mengisi dropdownlist dengan enum sebagai sumber datanya, yang disebut OwFillDataWithEnum. Metode ini dapat digunakan dengan enum apa pun nanti.
Kemudian di halaman dengan dropdownlist bernama DropDownList1, saya mengatur di Page_Load berikut hanya satu baris kode sederhana untuk mengisi enum ke dropdownlist.
BiBongNet.OwFillDataWithEnum<HowNice>(DropDownList1, "BiBongNet");
Itu dia. Saya rasa dengan beberapa metode sederhana seperti ini, Anda dapat mengisi kontrol daftar apa pun dengan enum apa pun, tidak hanya sebagai nilai deskriptif tetapi juga teks yang dilokalkan untuk ditampilkan. Anda dapat menjadikan semua metode ini sebagai metode ekstensi untuk penggunaan yang lebih baik.
Semoga bantuan ini. Bagikan untuk dibagikan!
Berikut caranya:
public class BiBongNet { enum HowNice { ReallyNice, SortOfNice, NotNice } /// <summary> /// This method is for filling a listcontrol, /// such as dropdownlist, listbox... /// with an enum as the datasource. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="ctrl"></param> /// <param name="resourceClassName"></param> public static void OwFillDataWithEnum<T>(ListControl ctrl, string resourceClassName) { var owType = typeof(T); var values = Enum.GetValues(owType); for (var i = 0; i < values.Length; i++) { //Localize this for displaying listcontrol's text field. var text = OwToStringByCulture(resourceClassName, Enum.Parse(owType, values.GetValue(i).ToString()).ToString()); //This is for listcontrol's value field var key = (Enum.Parse(owType, values.GetValue(i).ToString())); //add values of enum to listcontrol. ctrl.Items.Add(new ListItem(text, key.ToString())); } } /// <summary> /// Get localized strings. /// </summary> /// <param name="resourceClassName"></param> /// <param name="resourceKey"></param> /// <returns></returns> public static string OwToStringByCulture(string resourceClassName, string resourceKey) { return (string)HttpContext.GetGlobalResourceObject(resourceClassName, resourceKey); } }
sumber
Enum HowNice { [Description("Really Nice")] ReallyNice, [Description("Kinda Nice")] SortOfNice, [Description("Not Nice At All")] NotNice }
Untuk mengatasi ini, Anda harus menggunakan Metode ekstensi dan Array of Strings seperti ini:
Enum HowNice { ReallyNice = 0, SortOfNice = 1, NotNice = 2 } internal static class HowNiceIsThis { const String[] strings = { "Really Nice", "Kinda Nice", "Not Nice At All" } public static String DecodeToString(this HowNice howNice) { return strings[(int)howNice]; } }
Kode sederhana dan decoding cepat.
sumber
Saya mencoba pendekatan ini dan berhasil untuk saya.
Saya membuat kelas pembungkus untuk enum dan membebani operator implisit sehingga saya dapat menetapkannya ke variabel enum (dalam kasus saya, saya harus mengikat objek ke
ComboBox
nilai).Anda dapat menggunakan refleksi untuk memformat nilai enum seperti yang Anda inginkan, dalam kasus saya, saya mengambil
DisplayAttribute
keluar dari nilai enum (jika ada).Semoga ini membantu.
public sealed class EnumItem<T> { T value; public override string ToString() { return Display; } public string Display { get; private set; } public T Value { get; set; } public EnumItem(T val) { value = val; Type en = val.GetType(); MemberInfo res = en.GetMember(val.ToString())?.FirstOrDefault(); DisplayAttribute display = res.GetCustomAttribute<DisplayAttribute>(); Display = display != null ? String.Format(display.Name, val) : val.ToString(); } public static implicit operator T(EnumItem<T> val) { return val.Value; } public static implicit operator EnumItem<T>(T val) { return new EnumItem<T>(val); } }
EDIT:
Untuk berjaga-jaga, saya menggunakan fungsi berikut untuk mendapatkan
enum
nilai yang saya gunakan untukDataSource
dariComboBox
public static class Utils { public static IEnumerable<EnumItem<T>> GetEnumValues<T>() { List<EnumItem<T>> result = new List<EnumItem<T>>(); foreach (T item in Enum.GetValues(typeof(T))) { result.Add(item); } return result; } }
sumber
Setelah Anda memiliki
GetDescription
metode (harus statis global), Anda dapat menggunakan ini melalui metode ekstensi:public static string ToString(this HowNice self) { return GetDescription<HowNice>(self); }
sumber
Enum HowNice { [StringValue("Really Nice")] ReallyNice, [StringValue("Kinda Nice")] SortOfNice, [StringValue("Not Nice At All")] NotNice } Status = ReallyNice.GetDescription()
sumber
Anda dapat mendefinisikan Enum sebagai
Enum HowNice { [StringValue("Really Nice")] ReallyNice, [StringValue("Kinda Nice")] SortOfNice, [StringValue("Not Nice At All")] NotNice }
dan kemudian gunakan
HowNice.GetStringValue()
.sumber