combobox multiple valuemember single displaymember c#

7.8k views Asked by At

I have data like this...

id->name->floor
1->store1->1
2->store2->1
3->store2->2
4->store2->3
5->store3->2

I want add it in the combobox with display like this...

store1          
store2          
store3          

When I choose store2 I want get valuemember = 2, 3, 4

I think a logic (I'm not yet try at code)...
When I choose store2 I just get valuemember = 2 after that I check at database which id have same name in table. But I have 500++ data, so I think it's to waste process

Any idea??

note : example this is just sample form, i don't know how to code, i just make design
it will be helpfull if you give me implementation to combobox not to cmd

3

There are 3 answers

0
Scott Yang On

Do you want to be easy to retrieve the data in selected items? I prefer to fill data with its special type so that can get data directly from seleted items. because the Combox.Item.Add() function needs a prameter in Object type, so, I suggest that you can firstly define your data in a new type, like this:

/// <summary>
/// my own data define
/// </summary>
public class MyFloor
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Floor { get; set; }

    //very important, the result will be displayed in the combox
    public override string ToString()
    {
        return string.Format("{0}->{1}->{2}", ID, Name, Floor);
    }
}

then, you can fill the data into combox in special type:

void FillData()
    {
        //load data from txt or database
        List<MyFloor> floorList = new List<MyFloor>(){
            new MyFloor{ID=1, Name="store1", Floor="1"},
            new MyFloor{ID=2, Name="store2", Floor="1"},
            new MyFloor{ID=3, Name="store2", Floor="2"},
            new MyFloor{ID=4, Name="store2", Floor="3"},
            new MyFloor{ID=5, Name="store3", Floor="2"}
            };
        //fill into combox
        foreach (MyFloor floor in floorList)
        {
            this.comboBox1.Items.Add(floor);
        }
    }

at last, you can get your data directly:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        //retrieve data from selected item as MyFloor object
        MyFloor floor = this.comboBox1.SelectedItem as MyFloor;
        //show the selected data object
        if (floor != null)
        {
            txtID.Text = floor.ID.ToString();
            txtName.Text = floor.Name;
            txtFloor.Text = floor.Floor;
        }
    }

here is my result: result show

0
Markus On

You can group the data before putting them into the ComboBox. I've put together a small sample (follow the link to run or change it):

using System;
using System.Collections.Generic;
using System.Linq;

    public class MyData
    {

    public int Id { get; set; }
    public string Name { get; set; }
    public int Floor { get; set; }
}

public class MyGroupedData
{
    public string Name { get; set; }
    public IEnumerable<int> Floors { get; set; }
}

public class Test
{
    public static void Main()
    {
        MyData[] data = { 
            new MyData() { Id = 1, Name = "Store1", Floor = 1 }, 
            new MyData() { Id = 2, Name = "Store2", Floor = 1 }, 
            new MyData() { Id = 3, Name = "Store2", Floor = 2 }, 
            new MyData() { Id = 4, Name = "Store2", Floor = 3 }, 
            new MyData() { Id = 5, Name = "Store3", Floor = 2 },
        };
        var groupedData = from x in data group x by x.Name into grp 
            select new MyGroupedData() { Name = grp.Key, Floors = grp.Select(y => y.Floor) };
        foreach(var g in groupedData)
            Console.WriteLine("{0} -> {1}", g.Name, string.Join(", ", g.Floors.Select(x => x.ToString()).ToArray()));
    }
}

Though this sample is a Console application, I hope it shows the main steps you need to solve your problem. You bind the ComboBox to the result of the grouping operation and access the selected item by using the SelectedItem property. Also, you can set the value member to "Floors" in order to use the SelectedValue property.
In addition, you set the display member to "Name" so that the ComboBox shows the name.
One thing to note is that when grouping, you loose the id of the records. If this is a valuable information in this case, you'd need to adjust the grouping statement so that it not only takes the floor, but also the id into the group items. If the id is the same for a store name (which is not the case in your sample data), you could add an Id property to the MyGroupedData class.

0
pedritin On

.NET has the capability to accept LINQ Results, Lists, DataSets, etc. in the DataSource property. You could do something like this:

    comboBox.DataSource = DataSetObject;
    comboBox.DisplayMember = "DataTableFromDataSetObject.nameColumn";
    comboBox.ValueMember = "DataTableFromDataSetObject.idColumn";
    /*-------OR LINQ OBJECT-----------*/

    comboBox.DataSource = (from dt.Select() in row  
                        select new {name = row["nameColumn"],id = row["idColumn"]}).ToList();
    comboBox.DisplayMember = "nameColumn";
    comboBox.ValueMember = "idColumn";

I hope this should be useful to your ask