[C#] ComboBox: aggiunta di testo e valore a un articolo (nessuna origine vincolante)


Answers

// 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;
Question

In C # WinApp, come posso aggiungere sia il testo che il valore agli elementi del mio ComboBox? Ho fatto una ricerca e solitamente le risposte stanno usando "Binding to a source" .. ma nel mio caso non ho una fonte di binding pronta nel mio programma ... Come posso fare qualcosa del genere:

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



Migliore soluzione qui;

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

Retreive Data

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



Oltre alla risposta di Adam Markowitz, ecco un modo generale di (relativamente) semplicemente impostare i valori ItemSource di una combobox come enums , mentre mostra l'attributo 'Descrizione' all'utente. (Si potrebbe pensare che tutti vorrebbero farlo in modo tale che sia un .NET uno di linea, ma non lo è, e questo è il modo più elegante che ho trovato).

Innanzitutto, crea questa semplice classe per convertire qualsiasi valore Enum in un oggetto 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;
    }
}

In secondo luogo nel gestore di eventi OnLoad , è necessario impostare l'origine della casella combinata in modo che sia un elenco di ComboEnumItems basato su ogni Enum del tipo Enum . Questo può essere ottenuto con Linq. Quindi imposta semplicemente 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";
    }

Ora l'utente selezionerà da un elenco delle Descriptions , ma quello che selezionerà sarà il valore enum che è possibile utilizzare nel codice. Per accedere alla selezione dell'utente nel codice, comboBoxUserReadable.SelectedItem sarà ComboEnumItem e comboBoxUserReadable.SelectedValue sarà EMyEnum .




Un esempio che utilizza 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();



//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);



È necessario utilizzare l'oggetto dynamic per risolvere l'elemento della casella combinata in fase di esecuzione.

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

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

(comboBox.SelectedItem as dynamic).Value



Classe creat:

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

Codici 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);

        }

    }
}



Puoi usare un tipo generico:

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

Esempio di utilizzo di un semplice 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);
    }



Non so se questo funzionerà per la situazione indicata nel post originale (non importa il fatto che questo è due anni dopo), ma questo esempio funziona per me:

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

Per leggere nuovamente il valore, è necessario eseguire il cast della proprietà SelectedItem su un oggetto DictionaryEntry e quindi è possibile valutare le proprietà Key e Value di tale oggetto. Per esempio:

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



Questo è simile ad alcune delle altre risposte, ma è compatto ed evita la conversione al dizionario se hai già una lista.

Dato un ComboBox "combobox" su un form di Windows e una classe SomeClass con la proprietà del tipo string Name ,

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

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

Il che significa che l'oggetto SelectedItem è un oggetto SomeClass list e ogni elemento nella combobox verrà visualizzato utilizzando il suo nome.