ComboBox : 항목에 텍스트 및 값 추가 (바인딩 소스 없음)


202

C # WinApp에서 ComboBox의 항목에 텍스트와 값을 모두 추가하려면 어떻게해야합니까? 검색을 수행 한 결과 대개 "소스에 바인딩"을 사용하고 있습니다.하지만 제 경우에는 제 프로그램에 바인딩 소스가 준비되어 있지 않습니다. 어떻게하면 다음과 같은 작업을 수행 할 수 있습니까?

combo1.Item[1] = "DisplayText";
combo1.Item[1].Value = "useful Value"

답변:


361

원하는 텍스트를 반환하려면 고유 한 클래스 유형을 만들고 ToString () 메서드를 재정의해야합니다. 사용할 수있는 간단한 클래스 예는 다음과 같습니다.

public class ComboboxItem
{
    public string Text { get; set; }
    public object Value { get; set; }

    public override string ToString()
    {
        return Text;
    }
}

다음은 사용법의 간단한 예입니다.

private void Test()
{
    ComboboxItem item = new ComboboxItem();
    item.Text = "Item text1";
    item.Value = 12;

    comboBox1.Items.Add(item);

    comboBox1.SelectedIndex = 0;

    MessageBox.Show((comboBox1.SelectedItem as ComboboxItem).Value.ToString());
}

4
이 새로운 클래스 ComboboxItem이 정말로 필요합니까? ListItem이라는 것이 이미 있다고 생각합니다.
Amr Elgarhy 2016 년

15
WinForms가 아닌 ASP.NET에서만 사용할 수 있다고 생각합니다.
Adam Markowitz

1
항목은 항목의 데이터 (텍스트, 값, 다른 개체에 대한 참조 등)를 저장하는 데만 사용되는 별도의 유형입니다. ComboBox의 자손이 아니며 매우 드물게 나타납니다.
Adam Markowitz 2016 년

1
나는 파티에 다소 늦었다는 것을 알고 있지만 순수한 Windows 양식 환경 에서이 작업을 수행하는 방법은 데이터 테이블을 설정하고 항목을 추가하며 콤보 상자를 데이터 테이블에 바인딩하는 것이 었습니다. 더 깔끔한 방법이 있어야한다고 생각하지만 찾지 못했습니다 (DisplayMember는 텍스트를 표시 할 콤보 박스의 속성, 데이터의 값은 ValueMember)
user2366842

4
"SelectedValue"를 받거나 값을 기준으로 항목을 선택하는 방법 ... 답장하십시오.
Alpha Gabriel V. Timbol

185
// Bind combobox to dictionary
Dictionary<string, string>test = new Dictionary<string, string>();
        test.Add("1", "dfdfdf");
        test.Add("2", "dfdfdf");
        test.Add("3", "dfdfdf");
        comboBox1.DataSource = new BindingSource(test, null);
        comboBox1.DisplayMember = "Value";
        comboBox1.ValueMember = "Key";

// Get combobox selection (in handler)
string value = ((KeyValuePair<string, string>)comboBox1.SelectedItem).Value;

2
완벽하게 작동하며 선택한 답변이어야합니다. 그러나 .SelectedItem을 캐스팅하고 .Value를 사용하는 대신 comboBox1.SelectedText를 사용할 수 없습니까?
Jeffrey Goines

@fab 특정 키를 사용하여 콤보 박스에서 항목을 찾는 방법
Smith

사전 키를 기준으로 콤보 박스에서 항목을 선택할 수 있습니까? 키 3 선택과 같이 키 3 항목이 선택됩니다.
Dror

이 방법은 더 이상 vs2015에서 작동하지 않습니다. 새로운 디스플레이 멤버 및 Valuemember에 바인딩 할 수 없다는 예외가 발생했습니다
Plater

119

다음과 같이 익명 클래스를 사용할 수 있습니다.

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

comboBox.Items.Add(new { Text = "report A", Value = "reportA" });
comboBox.Items.Add(new { Text = "report B", Value = "reportB" });
comboBox.Items.Add(new { Text = "report C", Value = "reportC" });
comboBox.Items.Add(new { Text = "report D", Value = "reportD" });
comboBox.Items.Add(new { Text = "report E", Value = "reportE" });

업데이트 : 위의 코드가 제대로 콤보 상자에 표시되지만, 당신은 사용할 수 없습니다 SelectedValue또는 SelectedText속성 ComboBox. 이를 사용하려면 콤보 상자를 다음과 같이 바인딩하십시오.

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

var items = new[] { 
    new { Text = "report A", Value = "reportA" }, 
    new { Text = "report B", Value = "reportB" }, 
    new { Text = "report C", Value = "reportC" },
    new { Text = "report D", Value = "reportD" },
    new { Text = "report E", Value = "reportE" }
};

comboBox.DataSource = items;

14
프로그래머가 이것과 함께 for 루프를 필요로하기 때문에 이것을 약간 수정하고 싶습니다. 배열 대신 목록을 사용한 List<Object> items = new List<Object>(); 다음 items.Add( new { Text = "report A", Value = "reportA" } );루프 내에서 메서드를 사용할 수있었습니다 .
앤드류

1
앤드류, List <Object>가 SelectedValue 속성과 작동하도록 했습니까?
Peter PitLock

@Venkat,comboBox.SelectedItem.GetType().GetProperty("Value").GetValue(comboBox.SelectedItem, null)
Optavius

2
@Venkat 두 번째 솔루션을 설정 하면 콤보 상자 DataSourceSelectedValue또는 SelectedText속성을 사용할 수 있으므로 특별한 캐스팅을 수행 할 필요가 없습니다.
JPProgrammer

32

dynamic런타임에 콤보 박스 항목을 해결 하려면 객체를 사용해야 합니다.

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

comboBox.Items.Add(new { Text = "Text", Value = "Value" });

(comboBox.SelectedItem as dynamic).Value

1
이것은 별도의 클래스를 만들고 ToString ()을 재정의하는 것보다 훨씬 좋습니다.
Don Shrout

1
dynamic은 C # 4 이상에서만 사용할 수 있습니다. (.NET 4.5 생각합니다)
MickeyfAgain_BeforeExitOfSO

간단하고 빠르게 쓸 수 있습니다! VB.net의 SelectedValue에 대해이 작업을 수행했습니다. Dim Value As String = CType (Me.SectionIDToComboBox.SelectedItem, Object) .Value
Hannington Mambo

1
그렇다면 "값"을 사용하여 올바른 콤보 상자 항목을 설정하려면 어떻게해야합니까?
Dave Ludwig

17

Dictionary텍스트와 값을 추가하기 위해 사용자 정의 클래스를 만드는 대신 Object를 사용할 수 있습니다 .Combobox .

Dictionary객체 에 키와 값을 추가하십시오 .

Dictionary<string, string> comboSource = new Dictionary<string, string>();
comboSource.Add("1", "Sunday");
comboSource.Add("2", "Monday");

소스 사전 오브젝트를 Combobox다음에 바인딩하십시오 .

comboBox1.DataSource = new BindingSource(comboSource, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";

키 및 값 검색 :

string key = ((KeyValuePair<string,string>)comboBox1.SelectedItem).Key;
string value = ((KeyValuePair<string,string>)comboBox1.SelectedItem).Value;

전체 소스 : Combobox Text nd Value


14

이것은 방금 떠오른 방법 중 하나입니다.

combo1.Items.Add(new ListItem("Text", "Value"))

그리고 항목의 텍스트 또는 값을 변경하려면 다음과 같이 할 수 있습니다.

combo1.Items[0].Text = 'new Text';

combo1.Items[0].Value = 'new Value';

Windows Forms 에는 ListItem이라는 클래스가 없습니다 . ASP.NET 에만 존재 하므로 @Adam Markowitz가 대답 에서했던 것과 같이 사용하기 전에 자신의 클래스를 작성해야합니다 .

이 페이지를 확인하면 도움이 될 수 있습니다.


2
내가 잘못 생각하지 않는 한,을 ListItem는 ASP.NET에서만 사용할 수 있습니다
아담 마코 위츠

yes :( 안타깝게도 ASP.net에만 있습니다. 이제 어떻게해야합니까?
Bohn

그런 다음 콤보 상자에서 SelectedValue 또는 SelectedText 속성의 요점은 무엇입니까?
JSON

11

이것이 원래 게시물에 주어진 상황에서 효과가 있는지 알지 못하지만 (이것이 2 년 후라는 사실을 염두에 두지 마십시오),이 예제는 저에게 효과적입니다.

Hashtable htImageTypes = new Hashtable();
htImageTypes.Add("JPEG", "*.jpg");
htImageTypes.Add("GIF", "*.gif");
htImageTypes.Add("BMP", "*.bmp");

foreach (DictionaryEntry ImageType in htImageTypes)
{
    cmbImageType.Items.Add(ImageType);
}
cmbImageType.DisplayMember = "key";
cmbImageType.ValueMember = "value";

값을 다시 읽으려면 SelectedItem 속성을 DictionaryEntry 개체로 캐스팅 한 다음 해당 Key 및 Value 속성을 평가해야합니다. 예를 들어 :

DictionaryEntry deImgType = (DictionaryEntry)cmbImageType.SelectedItem;
MessageBox.Show(deImgType.Key + ": " + deImgType.Value);

7
//set 
comboBox1.DisplayMember = "Value"; 
//to add 
comboBox1.Items.Add(new KeyValuePair("2", "This text is displayed")); 
//to access the 'tag' property 
string tag = ((KeyValuePair< string, string >)comboBox1.SelectedItem).Key; 
MessageBox.Show(tag);

5

누구든지 여전히 이것에 관심이 있다면, 텍스트와 모든 유형의 값을 가진 간단하고 유연한 클래스가 있습니다 (아담 Markowitz의 예와 매우 유사 함).

public class ComboBoxItem<T>
{
    public string Name;
    public T value = default(T);

    public ComboBoxItem(string Name, T value)
    {
        this.Name = Name;
        this.value = value;
    }

    public override string ToString()
    {
        return Name;
    }
}

를 사용하여 <T>선언보다 더 나은 value하여 AS를 object가진 있기 때문에,object 당신은 다음 각 항목에 대해 사용되는 유형을 추적해야 할 것, 그리고 제대로 그것을 사용하는 코드에서 캐스팅.

나는 꽤 오랫동안 내 프로젝트에서 그것을 사용 해왔다. 정말 편리합니다.


4

나는 fab의 대답을 좋아했지만 내 상황에 사전을 사용하고 싶지 않아서 튜플 목록을 대체했습니다.

// set up your data
public static List<Tuple<string, string>> List = new List<Tuple<string, string>>
{
  new Tuple<string, string>("Item1", "Item2")
}

// bind to the combo box
comboBox.DataSource = new BindingSource(List, null);
comboBox.ValueMember = "Item1";
comboBox.DisplayMember = "Item2";

//Get selected value
string value = ((Tuple<string, string>)queryList.SelectedItem).Item1;

3

DataTable을 사용하는 예 :

DataTable dtblDataSource = new DataTable();
dtblDataSource.Columns.Add("DisplayMember");
dtblDataSource.Columns.Add("ValueMember");
dtblDataSource.Columns.Add("AdditionalInfo");

dtblDataSource.Rows.Add("Item 1", 1, "something useful 1");
dtblDataSource.Rows.Add("Item 2", 2, "something useful 2");
dtblDataSource.Rows.Add("Item 3", 3, "something useful 3");

combo1.Items.Clear();
combo1.DataSource = dtblDataSource;
combo1.DisplayMember = "DisplayMember";
combo1.ValueMember = "ValueMember";

   //Get additional info
   foreach (DataRowView drv in combo1.Items)
   {
         string strAdditionalInfo = drv["AdditionalInfo"].ToString();
   }

   //Get additional info for selected item
    string strAdditionalInfo = (combo1.SelectedItem as DataRowView)["AdditionalInfo"].ToString();

   //Get selected value
   string strSelectedValue = combo1.SelectedValue.ToString();

3

이 코드를 사용하여 텍스트와 값이있는 콤보 상자에 일부 항목을 삽입 할 수 있습니다.

씨#

private void ComboBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
    combox.Items.Insert(0, "Copenhagen");
    combox.Items.Insert(1, "Tokyo");
    combox.Items.Insert(2, "Japan");
    combox.Items.Insert(0, "India");   
}

XAML

<ComboBox x:Name="combox" SelectionChanged="ComboBox_SelectionChanged_1"/>

솔루션을 설명하십시오.
Vaibhav Bajaj

간단히 다음과 같은 국가를 각각의 색인에 콤 박스에 추가하십시오. 색인이 0 인 옵션이있는 콤 박스가 나타납니다. 콤 박스를 클릭하면 다른 옵션이 표시됩니다
Muhammad Ahmad

이것은 ID의 경우 작동하지 않습니다. 이것은 단순히 목록을 색인화하는 방법 일뿐입니다. 질문에 관한 것이 아닙니다.
Mr Heelis

2

Adam Markowitz의 답변에 더하여, 여기에 (상대적으로) 단순히 ItemSource콤보 상자 의 값을로 설정 enums하고 사용자에게 '설명'속성을 표시 하는 일반적인 목적의 방법이 있습니다 . (모두가 .NET 이되도록 모든 사람 이이 작업을 원한다고 생각합니다 . one liner 하지만 실제로는 그렇지 않으며 이것이 내가 찾은 가장 우아한 방법입니다).

먼저 Enum 값을 ComboBox 항목으로 변환하기 위해이 간단한 클래스를 만듭니다.

public class ComboEnumItem {
    public string Text { get; set; }
    public object Value { get; set; }

    public ComboEnumItem(Enum originalEnum)
    {
        this.Value = originalEnum;
        this.Text = this.ToString();
    }

    public string ToString()
    {
        FieldInfo field = Value.GetType().GetField(Value.ToString());
        DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
        return attribute == null ? Value.ToString() : attribute.Description;
    }
}

두 번째로 OnLoad이벤트 처리기에서 콤보 상자의 소스 ComboEnumItems를 모든 유형 을 기반으로 하는 목록 으로 설정 Enum해야 Enum합니다. 이는 Linq를 통해 달성 할 수 있습니다. 그런 다음 DisplayMemberPath:

    void OnLoad(object sender, RoutedEventArgs e)
    {
        comboBoxUserReadable.ItemsSource = Enum.GetValues(typeof(EMyEnum))
                        .Cast<EMyEnum>()
                        .Select(v => new ComboEnumItem(v))
                        .ToList();

        comboBoxUserReadable.DisplayMemberPath = "Text";
        comboBoxUserReadable.SelectedValuePath= "Value";
    }

이제 사용자는 사용자에게 친숙한 목록에서 선택 Descriptions하지만 enum코드에서 사용할 수있는 값이 선택됩니다 . 코드에서 사용자의 선택에 액세스하려면 comboBoxUserReadable.SelectedItem될 것입니다 ComboEnumItemcomboBoxUserReadable.SelectedValue될 것입니다 EMyEnum.


1

일반적인 유형을 사용할 수 있습니다.

public class ComboBoxItem<T>
{
    private string Text { get; set; }
    public T Value { get; set; }

    public override string ToString()
    {
        return Text;
    }

    public ComboBoxItem(string text, T value)
    {
        Text = text;
        Value = value;
    }
}

간단한 int-Type을 사용하는 예 :

private void Fill(ComboBox comboBox)
    {
        comboBox.Items.Clear();
        object[] list =
            {
                new ComboBoxItem<int>("Architekt", 1),
                new ComboBoxItem<int>("Bauträger", 2),
                new ComboBoxItem<int>("Fachbetrieb/Installateur", 3),
                new ComboBoxItem<int>("GC-Haus", 5),
                new ComboBoxItem<int>("Ingenieur-/Planungsbüro", 9),
                new ComboBoxItem<int>("Wowi", 17),
                new ComboBoxItem<int>("Endverbraucher", 19)
            };

        comboBox.Items.AddRange(list);
    }

0

나는 같은 문제가 있었다, 내가 한 것은 새로운 것을 추가하는 것이었다 ComboBox 같은 인덱스의 값을 가진 다음 첫 번째 인덱스를 변경 한 다음 주 콤보를 변경하면 두 번째 인덱스의 인덱스가 동시에 변경 된 다음 값을 가져옵니다 두 번째 콤보의

이것은 코드입니다.

public Form1()
{
    eventos = cliente.GetEventsTypes(usuario);

    foreach (EventNo no in eventos)
    {
        cboEventos.Items.Add(no.eventno.ToString() + "--" +no.description.ToString());
        cboEventos2.Items.Add(no.eventno.ToString());
    }
}

private void lista_SelectedIndexChanged(object sender, EventArgs e)
{
    lista2.Items.Add(lista.SelectedItem.ToString());
}

private void cboEventos_SelectedIndexChanged(object sender, EventArgs e)
{
    cboEventos2.SelectedIndex = cboEventos.SelectedIndex;
}

0

클래스 creat :

namespace WindowsFormsApplication1
{
    class select
    {
        public string Text { get; set; }
        public string Value { get; set; }
    }
}

Form1 코드 :

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            List<select> sl = new List<select>();
            sl.Add(new select() { Text = "", Value = "" });
            sl.Add(new select() { Text = "AAA", Value = "aa" });
            sl.Add(new select() { Text = "BBB", Value = "bb" });
            comboBox1.DataSource = sl;
            comboBox1.DisplayMember = "Text";
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

            select sl1 = comboBox1.SelectedItem as select;
            t1.Text = Convert.ToString(sl1.Value);

        }

    }
}

0

Visual Studio 2013에서 수행하는 방식은 다음과 같습니다.

단품 :

comboBox1->Items->AddRange(gcnew cli::array< System::Object^  >(1) { L"Combo Item 1" });

여러 항목 :

comboBox1->Items->AddRange(gcnew cli::array< System::Object^  >(3)
{
    L"Combo Item 1",
    L"Combo Item 2",
    L"Combo Item 3"
});

클래스 재정의를하거나 다른 것을 포함 할 필요가 없습니다. 그리고 네 comboBox1->SelectedItemcomboBox1->SelectedIndex통화는 여전히 작동합니다.


0

이것은 다른 답변 중 일부와 비슷하지만 작고 이미 목록이 있으면 사전으로 변환하지 않습니다.

ComboBoxwindows 형식 의 "콤보 박스" SomeClassstringtype 속성을 가진 클래스 가 주어지면 Name,

List<SomeClass> list = new List<SomeClass>();

combobox.DisplayMember = "Name";
combobox.DataSource = list;

즉, SelectedItem은의 SomeClass객체 list이며 각 항목 combobox은 이름을 사용하여 표시됩니다.


진실! 나는 DisplayMember전에 사용 했다 ... 나는 항상 존재를 잊어 버렸습니다. 나는이 속성에주의를 기울이기 전에 찾은 솔루션에 익숙해졌으며 항상 도움이되지는 않습니다. 모든 클래스에 Name또는 Tag속성이 있거나 표시 텍스트로 임의로 사용할 수있는 문자열 속성 이있는 것은 아닙니다 .
Matheus Rocha

이것은 좋은 지적입니다. 클래스를 수정할 수 있으면 클래스에 이러한 속성을 추가하는 것이 좋습니다 (예 : 'ComboBoxText'속성 (사용 가능한 경우 ToString () 메서드를 반환 할 수 있음)). 또는 클래스를 수정할 수없는 경우 'ComboBoxText'속성을 구현할 수있는 파생 클래스를 만들 수 있습니다. ComboBox에 클래스를 여러 번 추가해야하는 경우에만 유용합니다. 그렇지 않으면 다른 답변 중 하나에서 설명한대로 사전을 사용하는 것이 더 간단합니다.
Alex Smith

알렉스, 나는 보통 이런 경우에 사용하는 정신에 답했다. 나는 그것이 당신이 말한 것에 매우 가깝거나 당신이 말한 것을 이해하지 못했을 것입니다. 일부 클래스는 재정의하지 않으려는 메소드를 구현해야 할 수도 있기 때문에 클래스에서 파생되지 않았습니다 (따라서 간단한 메소드가 base.Method();많이 있습니다). 파생 클래스를 만들어야합니다. 콤보 상자 또는 목록 상자에 추가하려는 각기 다른 유형에 대해 내가 만든 수업은 융통성이 있으며 추가 노력없이 모든 유형으로 사용할 수 있습니다. 내 대답을 아래에서보고 당신이 생각하는 것을 말하십시오 :)
Matheus Rocha

귀하의 답변은 콤보 상자에 추가하려는 각 유형에 대해 파생 클래스를 만드는 것보다 확실히 더 편리해 보입니다. 좋은 작업! 나는 '이름'과 같은 속성을 즉시 사용할 수 없다면 미래에 나는 당신의 답변이나 사전 답변과 같은 것을 사용할 것입니다 :)
Alex Smith

0

모든 것이 필요한 경우 (문자열) 최종 값인 경우 Windows 양식에 대한 매우 간단한 솔루션입니다. 항목 이름이 콤보 상자에 표시되고 선택한 값을 쉽게 비교할 수 있습니다.

List<string> items = new List<string>();

// populate list with test strings
for (int i = 0; i < 100; i++)
            items.Add(i.ToString());

// set data source
testComboBox.DataSource = items;

이벤트 핸들러에서 선택한 값의 값 (문자열)을 얻습니다.

string test = testComboBox.SelectedValue.ToString();

0

더 나은 해결책은 여기입니다.

Dictionary<int, string> userListDictionary = new Dictionary<int, string>();
        foreach (var user in users)
        {
            userListDictionary.Add(user.Id,user.Name);
        }

        cmbUser.DataSource = new BindingSource(userListDictionary, null);
        cmbUser.DisplayMember = "Value";
        cmbUser.ValueMember = "Key";

검색 데이터

MessageBox.Show(cmbUser.SelectedValue.ToString());

콤보 상자를 채울 수 있었지만 클릭하면 VS2019 에서이 오류가 발생합니다. COM 보이는 관리되는 클래스 'ComboBoxUiaProvider
MC9000
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.