Search code examples
c#winformscombobox

WinForm C#, Populate combobox based on two conditions


I need to populate combobox1 based on city selected and typename selected.

I populate the city combobox with:

        private void FillCityTable()
    {
        dtCity.Columns.Add("CityID", typeof(int));//ID will be a number
        dtCity.Columns.Add("CName");//defaults typof is string

        dtCity.Rows.Add(1, "Regina");
        dtCity.Rows.Add(2, "Saskatoon");
        dtCity.Rows.Add(3, "Winnipeg");
    }
        private void Form1_Load(object sender, EventArgs e)
    {
        FillCityTable();
        FillTypeTable();
        FillData();

        cboCity.DataSource = dtCity;
        cboCity.DisplayMember = "CName";
    }

I populate the 'Type' combobox based on city selected

        private void FillTypeTable()
    {
        dtType.Columns.Add("CityID", typeof(int));//ID will be a number
        dtType.Columns.Add("TypeName");//defaults typof is string

        dtType.Rows.Add(1, "H1");
        dtType.Rows.Add(1, "H2");
        dtType.Rows.Add(1, "H3");
        dtType.Rows.Add(2, "H2");
        dtType.Rows.Add(2, "H1");
        dtType.Rows.Add(2, "H3");
        dtType.Rows.Add(3, "H2");
    }
        private void cboCity_SelectedIndexChanged(object sender, EventArgs e)
    {
        dtSpecificType = dtType.Select("CityID =" + dtCity.Rows[cboCity.SelectedIndex]["CityID"]).CopyToDataTable();
        cboType.DataSource = dtSpecificType;
        cboType.DisplayMember = "TypeName";
    }

The main data table comes from a csv file. I need to populate the combobox1 with the username based on the city selected and the TypeName selected. So far I can only populate the Usernames base on city selected. How can I get the second criteria?

        private void cboType_SelectedIndexChanged(object sender, EventArgs e)
    {
        dtSpecificUserNames = dtUserName.Select("CityID =" + dtSpecificType.Rows[cboType.SelectedIndex]["CityID"]).CopyToDataTable();
        combobox1.DataSource = dtSpecificUserNames;
        combobox1.DisplayMember = "Username";
    }

CSV :

CityID,TypeName,Username,Password,MachineID,Picture_File
1,H1,User1,password1,MachineID 1,Airplane
1,H1,User3,password3,MachineID 3,Bread
1,H1,User8,password8,MachineID 8,Boat
1,H2,User11,password11,MachineID 11,Boat
1,H3,User2,password2,MachineID 2,Boat
1,H3,User10,password10,MachineID 10,Airplane
2,H1,User6,password6,MachineID 6,Bread
2,H2,User4,password4,MachineID 4,Airplane
2,H2,User7,password7,MachineID 7,Airplane
2,H3,User5,password5,MachineID 5,Boat
3,H2,User9,password9,MachineID 9,Bread

Need the type criteria as well as city criteria.

enter image description here


Solution

  • Make a copy of the DataTable, assign that to be the DataSource of cboType and then set the DefaultView.RowFilter on the copy. E.g:

    public static void TestComboBox() {
    
        DataTable table = GetDataTable();
        ComboBox combo1 = new ComboBox();
        ComboBox combo2 = new ComboBox();
        ComboBox combo3 = new ComboBox();
    
        combo1.DisplayMember = "CityId";
        combo1.ValueMember = "CityId";
        combo1.DataSource = table;
    
        combo2.DisplayMember = "TypeName";
        combo2.ValueMember = "TypeName";
        combo2.DataSource = table;
    
        DataTable table2 = table.DefaultView.ToTable(); // make a copy
    
        combo3.DisplayMember = "Username";
        combo3.DataSource = table2;
    
        EventHandler evt = (o, e) => {
            String cityId = (String) combo1.SelectedValue;
            String typeName = (String) combo2.SelectedValue;
            table2.DefaultView.RowFilter = String.Format("CityId = '{0}' and TypeName = '{1}'", cityId, typeName);
        };
    
        combo1.SelectedValueChanged += evt;
        combo2.SelectedValueChanged += evt;
    
        FlowLayoutPanel panel = new FlowLayoutPanel();
        panel.Controls.AddRange(new [] { combo1, combo2, combo3 });
        panel.Dock = DockStyle.Fill;
        Form f = new Form();
        f.Controls.Add(panel);
        Application.Run(f);
    }
    
    
    public static DataTable GetDataTable() {
    String data  =
    @"CityID,TypeName,Username,Password,MachineID,Picture_File
    1,H1,User1,password1,MachineID 1,Airplane
    1,H1,User3,password3,MachineID 3,Bread
    1,H1,User8,password8,MachineID 8,Boat
    1,H2,User11,password11,MachineID 11,Boat
    1,H3,User2,password2,MachineID 2,Boat
    1,H3,User10,password10,MachineID 10,Airplane
    2,H1,User6,password6,MachineID 6,Bread
    2,H2,User4,password4,MachineID 4,Airplane
    2,H2,User7,password7,MachineID 7,Airplane
    2,H3,User5,password5,MachineID 5,Boat
    3,H2,User9,password9,MachineID 9,Bread";
    
    String[] lines = data.SplitAndTrim('\r', '\n');
    String[] header = lines[0].SplitAndTrim(',');
    
    DataTable table = new DataTable();
    for (int i = 0; i < header.Length; i++)
        table.Columns.Add(header[i]);
    
    for (int i = 1; i < lines.Length; i++) {
        table.Rows.Add(lines[i].SplitAndTrim(','));
    }
    return table;
    }