Связывание перечисления с комбинированным полем WinForms, а затем его установка
многие люди ответили на вопрос о том, как связать enum с полем со списком в WinForms. Это примерно так:
comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
Но это довольно бесполезно, если вы не можете установить фактическое значение для отображения.
Я пробовал:
comboBox1.SelectedItem = MyEnum.Something; // Does not work. SelectedItem remains null
Я также пробовал:
comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something); // ArgumentOutOfRangeException, SelectedIndex remains -1
Есть ли у кого-нибудь идеи, как это сделать?
Ответы
Ответ 1
Enum
public enum Status { Active = 0, Canceled = 3 };
Установка выпадающих значений из него
cbStatus.DataSource = Enum.GetValues(typeof(Status));
Получение перечисления из выбранного элемента
Status status;
Enum.TryParse<Status>(cbStatus.SelectedValue.ToString(), out status);
Ответ 2
Упростить:
Сначала инициализируйте эту команду: (например, после InitalizeComponent()
)
yourComboBox.DataSource = Enum.GetValues(typeof(YourEnum));
Чтобы получить выбранный элемент в выпадающем списке:
YourEnum enum = (YourEnum) yourComboBox.SelectedItem;
Если вы хотите установить значение для выпадающего списка:
yourComboBox.SelectedItem = YourEnem.Foo;
Ответ 3
Код
comboBox1.SelectedItem = MyEnum.Something;
в порядке, проблема должна находиться в DataBinding. Назначения DataBinding выполняются после конструктора, главным образом при первом показе combobox. Попробуйте установить значение в событии Load. Например, добавьте этот код:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
comboBox1.SelectedItem = MyEnum.Something;
}
И проверьте, работает ли он.
Ответ 4
Try:
comboBox1.SelectedItem = MyEnum.Something;
редактирует:
Упс, вы уже это пробовали. Тем не менее, это сработало для меня, когда мой comboBox был установлен в DropDownList.
Вот мой полный код, который работает для меня (с DropDown и DropDownList):
public partial class Form1 : Form
{
public enum BlahEnum
{
Red,
Green,
Blue,
Purple
}
public Form1()
{
InitializeComponent();
comboBox1.DataSource = Enum.GetValues(typeof(BlahEnum));
}
private void button1_Click(object sender, EventArgs e)
{
comboBox1.SelectedItem = BlahEnum.Blue;
}
}
Ответ 5
Скажем, у вас есть следующее перечисление
public enum Numbers {Zero = 0, One, Two};
У вас должна быть структура для сопоставления этих значений с строкой:
public struct EntityName
{
public Numbers _num;
public string _caption;
public EntityName(Numbers type, string caption)
{
_num = type;
_caption = caption;
}
public Numbers GetNumber()
{
return _num;
}
public override string ToString()
{
return _caption;
}
}
Теперь верните массив объектов со всеми перечислениями, сопоставленными с строкой:
public object[] GetNumberNameRange()
{
return new object[]
{
new EntityName(Number.Zero, "Zero is chosen"),
new EntityName(Number.One, "One is chosen"),
new EntityName(Number.Two, "Two is chosen")
};
}
И используйте следующее, чтобы заполнить поле со списком:
ComboBox numberCB = new ComboBox();
numberCB.Items.AddRange(GetNumberNameRange());
Создайте функцию для извлечения типа перечисления на всякий случай, если вы хотите передать его функции
public Numbers GetConversionType()
{
EntityName type = (EntityName)numberComboBox.SelectedItem;
return type.GetNumber();
}
и тогда вы должны быть в порядке:)
Ответ 6
Попробуйте следующее:
// fill list
MyEnumDropDownList.DataSource = Enum.GetValues(typeof(MyEnum));
// binding
MyEnumDropDownList.DataBindings.Add(new Binding("SelectedValue", StoreObject, "StoreObjectMyEnumField"));
StoreObject - это мой объектный пример с свойством StoreObjectMyEnumField для значения MyEnum для хранилища.
Ответ 7
это решение
для загрузки элемента перечисления в поле со списком:
comboBox1.Items.AddRange( Enum.GetNames(typeof(Border3DStyle)));
И затем используйте элемент перечисления как текст:
toolStripStatusLabel1.BorderStyle = (Border3DStyle)Enum.Parse(typeof(Border3DStyle),comboBox1.Text);
Ответ 8
public static void FillByEnumOrderByNumber<TEnum>(this System.Windows.Forms.ListControl ctrl, TEnum enum1, bool showValueInDisplay = true) where TEnum : struct
{
if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");
var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
select
new
KeyValuePair<TEnum, string>( (enumValue), enumValue.ToString());
ctrl.DataSource = values
.OrderBy(x => x.Key)
.ToList();
ctrl.DisplayMember = "Value";
ctrl.ValueMember = "Key";
ctrl.SelectedValue = enum1;
}
public static void FillByEnumOrderByName<TEnum>(this System.Windows.Forms.ListControl ctrl, TEnum enum1, bool showValueInDisplay = true ) where TEnum : struct
{
if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");
var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
select
new
KeyValuePair<TEnum,string> ( (enumValue), enumValue.ToString() );
ctrl.DataSource = values
.OrderBy(x=>x.Value)
.ToList();
ctrl.DisplayMember = "Value";
ctrl.ValueMember = "Key";
ctrl.SelectedValue = enum1;
}
Ответ 9
Основываясь на ответе от @Amir Shenouda, я получаю следующее:
Определение enum:
public enum Status { Active = 0, Canceled = 3 };
Установка выпадающих значений из него:
cbStatus.DataSource = Enum.GetValues(typeof(Status));
Получение перечисления из выбранного элемента:
Status? status = cbStatus.SelectedValue as Status?;
Ответ 10
public Form1()
{
InitializeComponent();
comboBox.DataSource = EnumWithName<SearchType>.ParseEnum();
comboBox.DisplayMember = "Name";
}
public class EnumWithName<T>
{
public string Name { get; set; }
public T Value { get; set; }
public static EnumWithName<T>[] ParseEnum()
{
List<EnumWithName<T>> list = new List<EnumWithName<T>>();
foreach (object o in Enum.GetValues(typeof(T)))
{
list.Add(new EnumWithName<T>
{
Name = Enum.GetName(typeof(T), o).Replace('_', ' '),
Value = (T)o
});
}
return list.ToArray();
}
}
public enum SearchType
{
Value_1,
Value_2
}
Ответ 11
public enum Colors
{
Red = 10,
Blue = 20,
Green = 30,
Yellow = 40,
}
comboBox1.DataSource = Enum.GetValues(typeof(Colors));
Полный источник... Связывание перечисления с Combobox
Ответ 12
Я использую следующий вспомогательный метод, который вы можете привязать к вашему списку.
''' <summary>
''' Returns enumeration as a sortable list.
''' </summary>
''' <param name="t">GetType(some enumeration)</param>
Public Shared Function GetEnumAsList(ByVal t As Type) As SortedList(Of String, Integer)
If Not t.IsEnum Then
Throw New ArgumentException("Type is not an enumeration.")
End If
Dim items As New SortedList(Of String, Integer)
Dim enumValues As Integer() = [Enum].GetValues(t)
Dim enumNames As String() = [Enum].GetNames(t)
For i As Integer = 0 To enumValues.GetUpperBound(0)
items.Add(enumNames(i), enumValues(i))
Next
Return items
End Function
Ответ 13
Преобразуйте перечисление в список строк и добавьте его в comboBox
comboBox1.DataSource = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();
Задайте отображаемое значение с помощью selectedItem
comboBox1.SelectedItem = SomeEnum.SomeValue;
Ответ 14
Ничто из этого не сработало для меня, но это сработало (и у него было дополнительное преимущество, заключающееся в том, что я мог лучше описать название каждого перечисления). Я не уверен, если это из-за обновлений.net или нет, но независимо от того, я думаю, что это лучший способ. Вам нужно будет добавить ссылку на:
using System.ComponentModel;
enum MyEnum
{
[Description("Red Color")]
Red = 10,
[Description("Blue Color")]
Blue = 50
}
....
private void LoadCombobox()
{
cmbxNewBox.DataSource = Enum.GetValues(typeof(MyEnum))
.Cast<Enum>()
.Select(value => new
{
(Attribute.GetCustomAttribute(value.GetType().GetField(value.ToString()), typeof(DescriptionAttribute)) as DescriptionAttribute).Description,
value
})
.OrderBy(item => item.value)
.ToList();
cmbxNewBox.DisplayMember = "Description";
cmbxNewBox.ValueMember = "value";
}
Затем, когда вы хотите получить доступ к данным, используйте эти две строки:
Enum.TryParse<MyEnum>(cmbxNewBox.SelectedValue.ToString(), out MyEnum proc);
int nValue = (int)proc;
Ответ 15
Вы можете использовать функции "FindString..":
Public Class Form1
Public Enum Test
pete
jack
fran
bill
End Enum
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.DataSource = [Enum].GetValues(GetType(Test))
ComboBox1.SelectedIndex = ComboBox1.FindStringExact("jack")
ComboBox1.SelectedIndex = ComboBox1.FindStringExact(Test.jack.ToString())
ComboBox1.SelectedIndex = ComboBox1.FindStringExact([Enum].GetName(GetType(Test), Test.jack))
ComboBox1.SelectedItem = Test.bill
End Sub
End Class
Ответ 16
comboBox1.SelectedItem = MyEnum.Something;
должен работать нормально... Как вы можете сказать, что SelectedItem
имеет значение null?
Ответ 17
Вы можете использовать список значений KeyValuePair в качестве источника данных для combobox. Вам понадобится вспомогательный метод, в котором вы можете указать тип перечисления, и он возвращает IEnumerable > где int - значение enum, а string - имя значения enum. В свой combobox установите для свойства DisplayMember свойство "Key" и ValueMember значение "Value". Value и Key - это общедоступные свойства структуры KeyValuePair. Затем, когда вы устанавливаете свойство SelectedItem в значение enum, как вы это делаете, оно должно работать.
Ответ 18
В настоящее время я использую свойство Items, а не DataSource, это означает, что мне нужно вызвать Add для каждого значения перечисления, но его все равно маленькое перечисление и его временный код.
Затем я могу просто сделать Convert.ToInt32 на значение и установить его с помощью SelectedIndex.
Временное решение, но YAGNI на данный момент.
Приветствия за идеи, я, вероятно, буду использовать их, когда буду делать правильную версию после получения обратной связи с клиентом.
Ответ 19
Старый вопрос, возможно, здесь, но у меня была проблема, и решение было простым и простым, я нашел это http://www.c-sharpcorner.com/UploadFile/mahesh/1220/
Он использует структуру данных и работает хорошо, поэтому проверьте это.
Ответ 20
comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
comboBox1.SelectedIndex = (int)MyEnum.Something;
comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something);
Обе эти работы для меня вы уверены, что нет ничего плохого?
Ответ 21
Общий метод установки перечисления в качестве источника данных для выпадающих страниц
Дисплей будет именем.
Выбранное значение будет представлять собой Enum
public IList<KeyValuePair<string, T>> GetDataSourceFromEnum<T>() where T : struct,IConvertible
{
IList<KeyValuePair<string, T>> list = new BindingList<KeyValuePair<string, T>>();
foreach (string value in Enum.GetNames(typeof(T)))
{
list.Add(new KeyValuePair<string, T>(value, (T)Enum.Parse(typeof(T), value)));
}
return list;
}
Ответ 22
Это всегда была проблема.
если у вас есть отсортированное перечисление, например от 0 до...
public enum Test
one
Two
Three
End
вы можете привязывать имена к combobox и вместо использования .SelectedValue
использовать свойство .SelectedIndex
Combobox.DataSource = System.Enum.GetNames(GetType(test))
и
Dim x as byte = 0
Combobox.Selectedindex=x
Ответ 23
В Framework 4 вы можете использовать следующий код:
Чтобы привязать перечисление MultiColumnMode к combobox, например:
cbMultiColumnMode.Properties.Items.AddRange(typeof(MultiColumnMode).GetEnumNames());
и получить выбранный индекс:
MultiColumnMode multiColMode = (MultiColumnMode)cbMultiColumnMode.SelectedIndex;
Примечание: в этом примере я использую выделение DevExpress, вы можете сделать то же самое в Win Form Combobox
Ответ 24
Немного поздно к этой вечеринке,
Метод SelectedValue.ToString() должен вызывать DisplayedName.
Однако в этой статье DataBinding Enum, а также с описаниями показан удобный способ не только иметь это, но вместо этого вы можете добавить атрибут пользовательского описания в перечисление и используйте его для отображаемого значения, если вы предпочитаете. Очень простая и простая и около 15 строк кода (если вы не считаете фигурные скобки) для всего.
Это довольно отличный код, и вы можете сделать его методом расширения для загрузки...
Ответ 25
используйте только приведение таким образом:
if((YouEnum)ComboBoxControl.SelectedItem == YouEnum.Español)
{
//TODO: type you code here
}
Ответ 26
Вы можете использовать метод расширения
public static void EnumForComboBox(this ComboBox comboBox, Type enumType)
{
var memInfo = enumType.GetMembers().Where(a => a.MemberType == MemberTypes.Field).ToList();
comboBox.Items.Clear();
foreach (var member in memInfo)
{
var myAttributes = member.GetCustomAttribute(typeof(DescriptionAttribute), false);
var description = (DescriptionAttribute)myAttributes;
if (description != null)
{
if (!string.IsNullOrEmpty(description.Description))
{
comboBox.Items.Add(description.Description);
comboBox.SelectedIndex = 0;
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
}
}
}
}
Как использовать... Объявите enum
using System.ComponentModel;
public enum CalculationType
{
[Desciption("LoaderGroup")]
LoaderGroup,
[Description("LadingValue")]
LadingValue,
[Description("PerBill")]
PerBill
}
Этот метод показывает описание в пунктах комбинированного списка.
combobox1.EnumForComboBox(typeof(CalculationType));
Ответ 27
Это, вероятно, никогда не будет замечено среди всех других ответов, но это код, который я придумал, у него есть преимущество использования DescriptionAttribute
, если он существует, но в противном случае использование имени самого значения enum.
Я использовал словарь, потому что у него есть готовый шаблон ключа/значения. List<KeyValuePair<string,object>>
также будет работать и без ненужного хеширования, но словарь поможет сделать код чище.
Я получаю членов, которые имеют MemberType
из Field
и которые являются буквальными. Это создает последовательность только членов, которые являются значениями перечисления. Это надежно, так как перечисление не может иметь другие поля.
public static class ControlExtensions
{
public static void BindToEnum<TEnum>(this ComboBox comboBox)
{
var enumType = typeof(TEnum);
var fields = enumType.GetMembers()
.OfType<FieldInfo>()
.Where(p => p.MemberType == MemberTypes.Field)
.Where(p => p.IsLiteral)
.ToList();
var valuesByName = new Dictionary<string, object>();
foreach (var field in fields)
{
var descriptionAttribute = field.GetCustomAttribute(typeof(DescriptionAttribute), false) as DescriptionAttribute;
var value = (int)field.GetValue(null);
var description = string.Empty;
if (!string.IsNullOrEmpty(descriptionAttribute?.Description))
{
description = descriptionAttribute.Description;
}
else
{
description = field.Name;
}
valuesByName[description] = value;
}
comboBox.DataSource = valuesByName.ToList();
comboBox.DisplayMember = "Key";
comboBox.ValueMember = "Value";
}
}