ComboBox: Bir Öğeye Metin ve Değer Ekleme (Bağlayıcı Kaynak Yok)


203

C # WinApp içinde, ComboBox öğelerinize hem Metin hem de Değer nasıl ekleyebilirim? Ben bir arama yaptım ve genellikle cevaplar "bir kaynağa bağlanma" kullanıyor .. ama benim durumumda benim programda hazır bir bağlayıcı kaynak yok ... Nasıl böyle bir şey yapabilirim:

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

Yanıtlar:


361

İstediğiniz metni döndürmek için kendi sınıf türünüzü oluşturmalı ve ToString () yöntemini geçersiz kılmalısınız. İşte kullanabileceğiniz bir sınıfın basit bir örneği:

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

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

Aşağıda kullanımı basit bir örnektir:

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
Bu yeni ComboboxItem sınıfına gerçekten ihtiyacımız var mı? Ben zaten ListItem denilen var olduğunu düşünüyorum.
Amr Elgarhy

15
WinForms değil, sadece ASP.NET'te kullanılabilir inanıyorum.
Adam Markowitz

1
Hayır. Öğe, yalnızca öğelerin verilerini (metin, değer, diğer nesnelere referanslar, vb.) Saklamak için kullanılan ayrı bir türdür. Bu bir ComboBox soyundan değildir ve olması çok nadir olurdu.
Adam Markowitz

1
Partiye biraz geç kaldığımı biliyorum, ama bunu saf pencereler form ortamında nasıl yaptığım, bir datatable kurmak, ona öğeler eklemek ve combobox'ı datatable'a bağlamaktı. Bir bunu yapmak için daha temiz bir yolu olması gerektiğini düşünürdüm, ama bir tane bulamadım (DisplayMember metin görünür için istediğiniz
açılan kutuda

4
"SelectedValue" değerini nasıl alabiliriz veya değere göre öğeyi nasıl seçebiliriz ... lütfen cevaplayın
Alpha Gabriel V.Timbol

187
// 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
Mükemmel çalışır ve bu seçilen cevap olmalıdır. Ancak .SelectedItem'i dökmek yerine .bodeBoot'yu kullanmak yerine comboBox1.SelectedText'i kullanamaz mıyız?
Jeffrey Goines

@fab Belirli bir tuşla birleşik giriş kutusundaki öğeyi nasıl bulursun
Smith

Sözlük Anahtarına dayalı olarak birleşik giriş kutusundaki bir öğeyi seçmek mümkün müdür? Anahtar 3'ü seçmek gibi Anahtar 3 ile Öğe seçilecektir.
Dror

Bu yöntem artık vs2015 için çalışmaz. Yeni teşhir üyesine ve Valuemember'e bağlanamamakla ilgili istisnalar
Plater

119

Anonim sınıfı aşağıdaki gibi kullanabilirsiniz:

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

GÜNCELLEME: Yukarıdaki kod birleşik giriş kutusunda düzgün bir şekilde görüntülenecek olsa da, SelectedValueveya SelectedTextözelliklerini kullanamayacaksınız ComboBox. Bunları kullanabilmek için birleşik giriş kutusunu aşağıdaki gibi bağlayın:

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
Bu biraz değiştirmek istiyorum çünkü bir programcı ile birlikte bir for döngüsü gerekir. Bir dizi yerine bir liste kullandım List<Object> items = new List<Object>(); Sonra items.Add( new { Text = "report A", Value = "reportA" } );döngü içinde yöntemi kullanabildi .
Andrew

1
Andrew, SelectedValue özelliğiyle çalışmak için List <Object> öğesini aldınız mı?
Peter PitLock

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

2
@Venkat, ikinci çözümü kullanırsanız, birleşik giriş kutusunun veya özelliklerini DataSourcekullanabilirsiniz , bu nedenle herhangi bir özel döküm yapmaya gerek yoktur. SelectedValueSelectedText
JPProgrammer

32

dynamicÇalışma zamanında combobox öğesini çözmek için nesne kullanmalısınız .

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

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

(comboBox.SelectedItem as dynamic).Value

1
Bu ayrı bir sınıf oluşturmak ve ToString () geçersiz kılmaktan çok daha iyidir.
Don Shrout

1
dinamik yalnızca C # 4 ve üstü sürümlerde kullanılabilir. (.NET 4.5 sanırım)
MickeyfAgain_BeforeExitOfSO

Basit ve hızlı yazma! Bunu VB.net SelectedValue için yaptım: Dim Value As String = CType (Me.SectionIDToComboBox.SelectedItem, Object) .Value
Hannington Mambo

1
Daha sonra, "Değer" kullanarak doğru birleşik giriş kutusu öğesi nasıl ayarlanır?
Dave Ludwig

17

DictionaryA'ya metin ve değer eklemek için özel bir sınıf oluşturmak yerine Nesne'yi kullanabilirsiniz Combobox.

DictionaryNesneye anahtarlar ve değerler ekleme :

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

Kaynak Sözlük nesnesini şuraya bağlayın Combobox:

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

Anahtar ve değeri al:

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

Tam Kaynak: Combobox Metin ve Değer


15

Akla yeni gelen yollardan biri:

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

Ve bir öğenin metnini veya değerini değiştirmek için bunu şu şekilde yapabilirsiniz:

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

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

Windows Forms'da ListItem adlı bir sınıf yoktur . Sadece ASP.NET'te var , bu yüzden kullanmadan önce kendi sınıfınızı yazmanız gerekecek, @Adam Markowitz'in cevabında yaptığı gibi .

Ayrıca bu sayfaları kontrol edin, yardımcı olabilirler:


2
Yanılmıyorsam, ListItem sadece ASP.NET'te mevcuttur
Adam Markowitz

evet :( maalesef sadece ASP.net'te ... şimdi ne yapabilirim?
Bohn

Sonra bir açılan kutudaki SelectedValue veya SelectedText özelliklerinin anlamı nedir?
JSON

11

Bunun orijinal gönderide verilen durum için işe yarayıp yaramayacağını bilmiyorum (bunun iki yıl sonra olduğu gerçeğini boş verin), ancak bu örnek benim için işe yarıyor:

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";

Değerinizi geri okumak için SelectedItem özelliğini bir DictionaryEntry nesnesine atamanız gerekir ve ardından bunun Anahtar ve Değer özelliklerini değerlendirebilirsiniz. Örneğin:

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

Herkes hala bununla ilgileniyorsa, burada bir metin ve herhangi bir türde bir değere sahip bir combobox öğesi için basit ve esnek bir sınıf (Adam Markowitz örneğine çok benzer):

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

Kullanılması <T>ilan daha iyidir valuebir şekilde objectsahip çünkü,object o zaman her öğe için kullanılan tip takip etmek olurdu ve düzgün kullanmak için kodunuza attı.

Uzun süredir projelerimde kullanıyorum. Gerçekten kullanışlı.


4

Fab'ın cevabını beğendim ama durumum için bir sözlük kullanmak istemedim, bu yüzden tuples listesini değiştirdim.

// 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 kullanan bir örnek:

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

Bu kodu, metin ve değer içeren bir birleşik giriş kutusuna bazı öğeler eklemek için kullanabilirsiniz.

C #

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"/>

Lütfen çözümünüzü açıklayın.
Vaibhav Bajaj

Basitçe, bir combox içinde kendi indekslerine aşağıdaki ülkeleri ekleyin. 0 dizininde bir seçenek içeren bir combox görüntülenir. Combox'ı tıklarsanız aşağıdaki diğer seçenek gösterilir
Muhammad Ahmad

bu id için işe yaramaz bu sadece listeyi indekslemenin bir yoludur, sorunun konusu bu değildir
Bay Heelis

2

Adam Markowitz'in cevabına ek olarak, kullanıcıya 'Açıklama' niteliğini gösterirken, ItemSourcebirleşik giriş kutusunun değerlerini (göreceli olarak) basitçe ayarlamanın genel amaçlı bir yolu enums. (Herkesin bunu yapmak isteyeceğini düşünüyorsunuz, böylece bir .NET olabilir tek astar olacaktı, ancak değil ve bulduğum en zarif yol bu).

İlk olarak, herhangi bir Enum değerini bir ComboBox öğesine dönüştürmek için bu basit sınıfı oluşturun:

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

İkincisi sizin de OnLoadolay işleyicisi, sen bir listesini olmak için açılan kutunun kaynağını ayarlamanız gerekir ComboEnumItemsher dayalı Enumsizin de Enumtip. Bu Linq ile elde edilebilir. Ardından DisplayMemberPathşunları ayarlayın :

    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";
    }

Şimdi kullanıcı, kullanıcı dostu listenizden Descriptionsseçim yapacaktır, ancak seçtikleri enumkodda kullanabileceğiniz değer olacaktır . Kullanıcının kod seçimine erişmek için comboBoxUserReadable.SelectedItem, ComboEnumItemve comboBoxUserReadable.SelectedValueolacak EMyEnum.


1

Genel bir Tür kullanabilirsiniz:

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

Basit bir int-Type kullanımına örnek:

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

Aynı sorunu yaşadım, yaptığım şey yeni bir şey eklemekti ComboBox sadece aynı endeksten sonra sadece bir değeri ile , ve sonra ana combo indeks ikinci bir değiştirdiğinizde aynı anda değiştirmek, sonra değeri almak ikinci combo ve kullanın.

Bu kod:

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

Sınıf yaratma:

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

Form1 Kodları:

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 bunu yapar:

Tek ürün:

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

Birden Fazla Ürün:

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

Sınıf geçersiz kılmaya veya başka bir şey eklemeye gerek yok. Ve evet comboBox1->SelectedItemve comboBox1->SelectedIndexçağrılar hala çalışıyor.


0

Bu, diğer bazı cevaplara benzer, ancak kompakttır ve zaten bir listeniz varsa sözlüğe dönüştürmeyi önler.

ComboBoxWindows formunda bir " SomeClassaçılan kutu" ve stringtype özelliğine sahip bir sınıf verildiğinde Name,

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

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

Bu, SelectedItem öğesinin bir SomeClassnesne olduğu listve içindeki her öğenin comboboxadı kullanılarak görüntüleneceği anlamına gelir .


Doğru! Daha DisplayMemberönce kullandım ... Her zaman var olduğunu unuturum. Bu özelliğe dikkat etmeden önce bulduğum çözüme alıştım, ayrıca her zaman yardımcı olmayacak. Tüm sınıfların bir Nameveya Tagözelliği yoktur veya isteğe bağlı olarak bir görüntüleme metni olarak kullanılabilen bir string özelliği yoktur.
Matheus Rocha

Bu iyi bir nokta. Sınıfı değiştirebiliyorsanız, sınıfa böyle bir özellik, örneğin 'ComboBoxText' (varsa ToString () yöntemini döndürebilir) özelliği eklemeye değer olabilir. Alternatif olarak, sınıf değiştirilemezse, 'ComboBoxText' özelliğinin uygulanabileceği türetilmiş bir sınıf oluşturmak mümkün olabilir. Bu, sınıfı bir ComboBox'a birçok kez eklemek zorunda kalırsanız buna değecektir. Aksi takdirde, diğer cevaplardan birinde açıklandığı gibi bir sözlük kullanmak daha kolaydır.
Alex Smith

Hey Alex, bu durumlarda genellikle kullandığım ethod ile bir cevap verdim. Bence söylediklerinize çok yakın ya da belki söylediklerinizi anlamadım. Sınıftan türetmedim çünkü bazı sınıflar geçersiz kılmak istemediğimiz yöntemleri uygulamanızı gerektirebilir (bu yüzden basit bir yöntemle bir grup yöntemimiz olurdu base.Method();), ayrıca bir türev sınıf oluşturmanız gerekir birleşik giriş kutularına veya liste kutularına eklemek istediğiniz her farklı tür için. Yaptığım sınıf esnektir, ekstra çaba harcamadan her türle kullanabilirsiniz. Cevabım için aşağıya bakın ve ne düşündüğünüzü söyleyin :)
Matheus Rocha

Katılıyorum, cevabınız kesinlikle bir açılan kutuya eklemek istediğiniz her tür için türetilmiş bir sınıf oluşturmaktan daha uygun görünüyor. İyi iş! Gelecekte 'İsim' gibi bir mülkünüz yoksa, sanırım cevabınız veya sözlük cevabınız gibi bir şey kullanacağım :)
Alex Smith

0

Eğer tüm gerekli bir (dize) olarak son değer ise, bu windows formları için çok basit bir çözümdür. Öğelerin adları Açılan Kutu'da görüntülenir ve seçilen değer kolayca karşılaştırılabilir.

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;

ve olay işleyicisinde seçilen değerin değerini (dize) alır

string test = testComboBox.SelectedValue.ToString();

0

Burada daha iyi çözüm;

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";

Verileri Al

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

Ben combobox doldurmak mümkün iken, VS2019 bu hatayı verirken COM görünür yönetilen sınıf 'ComboBoxUiaProvider
MC9000
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.