2009-05-25 3 views
82

Многие люди ответили на вопрос о том, как связать enum с полем со списком в WinForms. Это примерно так:Связывание перечисления с комбинированным полем 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 

Кто-нибудь есть какие-либо идеи, как это сделать?

+2

Почему просто не попробовать ComboBox.SelectedValue вместо этого? –

+5

Если на ваш вопрос был дан ответ, вы действительно должны выбрать ответ. –

+0

Точка привязки перечисления не совсем ясна. Перечисление, вероятно, не изменится во время выполнения. Вы также можете написать метод расширения, который заполнил бы коллекцию элементов combobox всеми значениями перечисления. – Andreas

ответ

6

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; 
    } 
} 
+0

интересный, здорово, что вы можете сделать 'comboBox1.SelectedItem = BlahEnum.Blue;' но что, если вы хотите, чтобы в combobox вещи были строками, например. элемент combobox для «жевательной витаминной таблетки».? – barlop

0

Вы можете использовать "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 
0
comboBox1.SelectedItem = MyEnum.Something; 

должен работать просто отлично ... Как вы можете сказать, что SelectedItem имеет значение null?

+0

Я могу проверить его в отладчике. Я предполагаю, что это потому, что тип SelectedItem является объектом, то есть ссылочным типом и перечислениями являются типы значений. Хотя я ожидал, что компилятор поймает это. – 2009-05-25 14:44:02

0

Вы можете использовать список значений KeyValuePair в качестве источника данных для combobox. Вам понадобится вспомогательный метод, в котором вы можете указать тип перечисления, и он возвращает IEnumerable> где int - значение enum, а string - имя значения enum. В свой combobox установите для свойства DisplayMember свойство «Key» и ValueMember значение «Value». Value и Key - это общедоступные свойства структуры KeyValuePair. Затем, когда вы устанавливаете свойство SelectedItem на значение перечисления, как вы это делаете, оно должно работать.

0

В настоящее время я использую свойство Items, а не DataSource, это означает, что я должен вызвать Add для каждого значения перечисления, но его небольшое перечисление и его временный код в любом случае.

Тогда я могу просто сделать Convert.ToInt32 по значению и установить его с помощью SelectedIndex.

Временное решение, но YAGNI на данный момент.

Приветствия за идеи, я, вероятно, буду использовать их, когда буду делать правильную версию после получения обратной связи с клиентами.

12

Код

comboBox1.SelectedItem = MyEnum.Something; 

нормально, проблема должна находиться в DataBinding. Назначения DataBinding выполняются после конструктора, главным образом при первом показе combobox. Попробуйте установить значение в событии Load. Например, добавьте этот код:

protected override void OnLoad(EventArgs e) 
{ 
    base.OnLoad(e); 
    comboBox1.SelectedItem = MyEnum.Something; 
} 

И проверьте, работает ли оно.

1

Я использую следующий вспомогательный метод, который вы можете привязать к своему списку.

''' <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 
11

Допустим, у вас есть следующее перечисление

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

, а затем вы должны быть в порядке :)

+0

+1 приятное решение. Недавно эта проблема возникла и была решена аналогичным образом (только с помощью «Tuple»). Я бы включил и значение enum и описание в свойства, затем добавьте 'numberCB.DisplayProperty =" Caption "'; 'и' numberCB.ValueProperty = "Num" ', чтобы вы могли напрямую использовать' SelectedValue' и привязываться к нему , – Alejandro

+0

IMHO, возможно, более полный исходный код примера, если также есть функция, например, добавить параметр «Все»/«Выбрать все» в ComboBox, используемый для фильтрации всех строк в поиске. – Kiquenet

2
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 
} 
+0

ИМХО, возможно, более полный образец исходного кода, если также есть функция, например, добавить параметр «Все»/«Выбрать все» в ComboBox, используемый для фильтрации всех строк в поиске. – Kiquenet

0

Старый вопрос, возможно здесь, но у меня была проблема, и решение было легко и просто, я нашел этот http://www.c-sharpcorner.com/UploadFile/mahesh/1220/

Он использует данные и работает хорошо, поэтому проверьте его.

0
comboBox1.DataSource = Enum.GetValues(typeof(MyEnum)); 

comboBox1.SelectedIndex = (int)MyEnum.Something; 

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something); 

Обе эти работы для меня вы уверены, что нет ничего плохого?

+1

Не уверен, что это сработает, если вы используете пользовательские значения enum, т. Е. 'Enum MyEnum {Something = 47}' –

2

это решение , чтобы загрузить элемент перечисления в выпадающий список:

comboBox1.Items.AddRange(Enum.GetNames(typeof(Border3DStyle))); 

И затем использовать элемент перечисления в виде текста:

toolStripStatusLabel1.BorderStyle = (Border3DStyle)Enum.Parse(typeof(Border3DStyle),comboBox1.Text); 
119

Enum

public enum Status { Active = 0, Canceled = 3 }; 

Настройка выпадающие значения из него

cbStatus.DataSource = Enum.GetValues(typeof(Status)); 

Получение перечисления от выбранного пункта

Status status; 
Enum.TryParse<Status>(cbStatus.SelectedValue.ToString(), out status); 
+4

Спасибо, это работает для меня. Имейте в виду, что tryparse - это .net 4.0 заявление. –

+0

Для меня SelectedValue всегда null. Похоже, что combobox не становится интуитивно понятным. (MyEnum) this.GridView.CurrentRow.Cells [ "comboColumnCell"]. Значение. Я вижу значение, но внутренне он выбрасывает исключение нулевого указателя – ssal

+3

Именно так OP не хочет использовать. Проблема в том, что пользователю отображается имя в коде каждого значения, которое подлежит рефакторингу, а не удобству для пользователя в большинстве случаев. – Alejandro

1

Преобразование перечисления в список строку и добавить к COMBOBOX

comboBox1.DataSource = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>(); 

Установите отображаемое значение с помощью SelectedItem

comboBox1.SelectedItem = SomeEnum.SomeValue; 
+0

это сработало для меня ... –

0

Общий метод установки перечисления в качестве datasour ce для выпадающих списков

Дисплей будет называться. Выбранное значение будет сама 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; 
    } 
0

Это всегда было проблемой. если у вас есть отсортированный Enum, как от 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 
3

Попробуйте следующее:

// fill list 
MyEnumDropDownList.DataSource = Enum.GetValues(typeof(MyEnum)); 

// binding 
MyEnumDropDownList.DataBindings.Add(new Binding("SelectedValue", StoreObject, "StoreObjectMyEnumField")); 

StoreObject - это пример моего объекта с свойством StoreObjectMyEnumField для значения MyEnum для магазина.

3
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; 
    } 
+0

Что значит? Я не понял ваш комментарий. этот метод расширения работает –

+0

Это зависит от того, разрешены ли ваши номера перечислений ИЛИ Флаги.Если это так, вы можете добавить флаг 255 с именем All и вызвать функцию с помощью All as enum1, которая создает значение по умолчанию. i.e. comboBox1.FillByEnumOrderByName (MyEnum.All) –

+0

Любой такой вариант: ** var l = values.OrderBy (x => x.Value) .ToList(); l.Insert (0, «Все»); ** – Kiquenet

0

В Framework 4 можно использовать следующий код:

Чтобы связать MultiColumnMode перечисление в COMBOBOX, например:

cbMultiColumnMode.Properties.Items.AddRange(typeof(MultiColumnMode).GetEnumNames()); 

и получить выбранный индекс:

MultiColumnMode multiColMode = (MultiColumnMode)cbMultiColumnMode.SelectedIndex; 

Примечание: Я использую DevExpress выпадающий в этом примере, вы можете сделать то же самое в Win Form Combobox

0

Немного поздно к этой партии,

SelectedValue.ToString() метод должен потянуть в Отображаемое имя. Однако в этой статье DataBinding Enum and also With Descriptions показан удобный способ не только этого, но вместо этого вы можете добавить атрибут атрибута в перечисление и использовать его для отображаемого значения, если хотите. Очень просто и легко и около 15 строк кода (если вы не считаете фигурные скобки) для всего.

Это довольно изящный код, и вы можете сделать его метод расширения для загрузки ...

10

Для упрощения:

инициализирован эту команду: (например,после того, как InitalizeComponent())

yourComboBox.DataSource = Enum.GetValues(typeof(YourEnum))

Чтобы получить выбранный элемент на выпадающий список
YourEnum enum = (YourEnum) yourComboBox.SelectedItem

Если вы хотите установить значение в поле со списком
yourComboBox.SelectedItem = YourEnem.Foo

+1

Это работает до тех пор, пока значение Display совпадает с значением параметра, иначе нет. –

2

На основании ответа от @Amir Шенуда В итоге я получаю:

Enum's def Inition:

public enum Status { Active = 0, Canceled = 3 }; 

Установка выпадающих значений из него:

cbStatus.DataSource = Enum.GetValues(typeof(Status)); 

Получения перечисления от выбранного пункта:

Status? status = cbStatus.SelectedValue as Status?; 
+1

Почему использование nullable? Вы можете использовать явное литье (заклинание) и не использовать значение NULL –

Смежные вопросы