我正在将数据库中的表加载到CheckedListBox
,现在我需要在用户更改第一个CheckedListBox
中项目的检查状态时检查哪些项目已被检查,然后将我的数据库中另一个表的相应部分添加到第二个CheckedListBox
。
例如,我有chlbMeal
和chlbFood
。在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);
}
}
我该怎么做?
答案 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
项目的子值。