多个CheckedListBox和数据库连接

时间:2015-07-09 21:14:53

标签: c# .net

我正在将数据库中的表加载到CheckedListBox,现在我需要在用户更改第一个CheckedListBox中项目的检查状态时检查哪些项目已被检查,然后将我的数据库中另一个表的相应部分添加到第二个CheckedListBox

例如,我有chlbMealchlbFood。在chlbMeal里面有“早餐”,“晚餐”和“午餐”。现在当用户选择其中任何一个时,我希望相应的食物选项显示在chlbFood中 - 例如,如果选中“早餐”,在chlbFood内我们有“炒鸡蛋”,“鸡蛋和培根“等等。

我的项目有所不同,但这是我想要在这部分实现的主要想法。这是我的代码:

private void chlbRadovi_SelectedIndexChanged(object sender, EventArgs e)
{
    try
    {
        if (chlbRadovi.CheckedItems.Count > 0)
        {
            int[] niz = new int[chlbRadovi.CheckedIndices.Count];
            chlbRadovi.CheckedIndices.CopyTo(niz, 0);
            foreach (int x in niz)
            {
                this.tipradovaTableAdapter1.Fill(this.ignaDataSet1.tipradova);
                SqlConnection con = new SqlConnection(Konekcija.con);
                SqlCommand cmd = new SqlCommand("select IDTR, Naziv from tipradova where IDRad in @IDRad", con);
                cmd.Parameters.AddWithValue("@IDRad", chlbRadovi.ValueMember[x]);
                SqlDataReader reader;

                chlbTipoviRadova.DataSource = ignaDataSet1.tipradova;
                chlbTipoviRadova.DisplayMember = "Naziv";
                chlbTipoviRadova.ValueMember = "IDTR";

                con.Open();
                reader = cmd.ExecuteReader();
                con.Close();
            }
        }
        else
        {
            chlbTipoviRadova.DataSource = null;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

我该怎么做?

1 个答案:

答案 0 :(得分:1)

好的,我们走了。首先,将数据绑定到您的第一个CheckedListbox

private string connectionString = "Your connection string";

private void cbListFirst_SetDataSource()
{
    // Using block will automatically close connection when it's not used anymore
    using (var con = new SqlConnection(connectionString))
    {
        SqlCommand cmd = con.CreateCommand();
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = @"SELECT Id, Name
                            FROM dbo.FoodTypes";

        try
        {
            con.Open();

            var foodTypes = new List<FoodType>();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                // Fill items for first CheckedListBox DataSource
                while (reader.Read())
                {
                    foodTypes.Add(new FoodType()
                    {
                        Id = (int)reader["Id"],
                        Name = reader["Name"] as string
                    });
                }
            }

            // Set first CheckedListBox DataSource
            cbListFirst.DataSource = foodTypes;
            cbListFirst.DisplayMember = "Name";
            cbListFirst.ValueMember = "Id";
        }
        catch (Exception ex)
        {
            // Clear DataSource and handle error (should be improved)
            cbListFirst.DataSource = null;
            MessageBox.Show("Error", ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

完成后,您应该将 ParentIds 封装在第一个DataSource的{​​{1}}内的 FoodType 对象中。现在,您不应该使用CheckedListbox事件,而应使用SelectedIndexChanged事件。因此,每次用户检查或取消选中其中一个项目时,都会触发事件。现在唯一的问题是,在此事件中,尚未应用已点击项目的新 CheckValue ,但由于我们在ItemCheck内有关于新旧值的信息,因此可以轻松处理。看看这个:

EventArgs

现在,您的第二个private void cbListFirst_ItemCheck(object sender, ItemCheckEventArgs e) { // Clear second CheckedListbox DataSource cbListSecond.DataSource = null; var ingridients = new List<Ingridient>(); foreach (var item in cbListFirst.CheckedItems) { // If item was previously checked, we want to skip it because it's new value is // unchecked and we shouldn't be adding it's child items to second CheckedListbox if (cbListFirst.Items.IndexOf(item) != e.Index) { var foodType = (FoodType)item; ingridients.AddRange(GetIngridientsForFoodType(foodType.Id)); } } // If item was previously unchecked, it's child items won't be caught in previous loop // so we want to explicitly include them inside this if-block if new value is checked if (e.NewValue == CheckState.Checked) { var foodType = (FoodType)cbListFirst.Items[e.Index]; ingridients.AddRange(GetIngridientsForFoodType(foodType.Id)); } // Finally, bind new DataSource cbListSecond.DataSource = ingridients; cbListSecond.DisplayMember = "Name"; cbListSecond.ValueMember = "Id"; } // This method returns list of Ingridients for single FoodType private List<Ingridient> GetIngridientsForFoodType(int foodTypeId) { using (var con = new SqlConnection(connectionString)) { SqlCommand cmd = con.CreateCommand(); cmd.CommandType = CommandType.Text; cmd.CommandText = @"SELECT Id, Name FROM dbo.Ingridients WHERE FoodTypeId = @FoodTypeId"; cmd.Parameters.AddWithValue("@FoodTypeId", foodTypeId); try { con.Open(); var ingridients = new List<Ingridient>(); using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { ingridients.Add(new Ingridient() { Id = (int)reader["Id"], Name = reader["Name"] as string }); } } return ingridients; } catch (Exception ex) { // Handle error (should be improved) and return null MessageBox.Show("Error", ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); return null; } } } 应填充第一个CheckedListbox项目的子值。