保留级联CheckedListBox中项目的检查状态 [英] Preserve check state of the items in cascading CheckedListBox
问题描述
我的C#Windows窗体应用程序中有2个 Checkedlistbox
控件。第一个 Checkedlistbox
用于医生的专长,例如牙医,放射线医生等。如果我选中牙医复选框,则医生的专长 Checkedlistbox
控件,所有牙医医生都会显示在医生姓名 Checkedlistbox
控件中。
问题是当我检查牙医<$ c $时c> Checkedlistbox ,然后是医生的 Checkedlistbox
的一些牙医,那么如果我检查放射科医生 Checkedlistbox
,然后医生的姓名 Checkedlistbox
将被重设,而我所有牙医已选中的复选框将被取消。
我尝试过的事情:
医生姓名 Checkedlistbox
数据源:
I have 2 Checkedlistbox
controls in my C# windows form application program. First Checkedlistbox
is for doctors' specialty for example dentist, radiologist and etc. If I check dentist checkbox doctors' specialty Checkedlistbox
control, all doctors who are dentist will be shown in the doctors' name Checkedlistbox
control.
The problem is that when I check dentist Checkedlistbox
and then some dentists from doctors' Checkedlistbox
, then if I check radiologist Checkedlistbox
, then doctors' name Checkedlistbox
will be reset and all my dentist checked checkbox will be de-selected.
What I have tried:
Doctors' name Checkedlistbox
data source:
DoctorsIDCheckedlistbox.DataSource = _ClinicEntities.Tbl_Doctors
.Where(w => _SelectedSpecialty.Contains(w.SpecialtyID))
.Select(s => new DoctorListCheckbox{ Name = s.Name + " " + s.LastName, DoctorID = s.DoctorID })
.ToList();
DoctorsIDCheckedlistbox.DisplayMember = "Name";
DoctorsIDCheckedlistbox.ValueMember = "DoctorID";
然后我将选中的项目保存在 ItemCheck
事件中:
Then I save checked items in ItemCheck
event:
private void DoctorsID_ItemCheck(object sender, ItemCheckEventArgs e)
{
int doctorID = Convert.ToInt32(DoctorsIDCheckedlistbox.SelectedValue);
if (e.NewValue == CheckState.Checked)
{
_SelectedDoctorsChecked.Add(doctorID.ToString());
}
else
{
_SelectedDoctorsChecked.Remove(doctorID.ToString());
}
}
然后选择医生专业 ItemCheck
事件:
Then for doctors' specialty ItemCheck
event:
private void SpecialtyTypeID_ItemCheck(object sender, ItemCheckEventArgs e)
{
for (int i = 0; i < DoctorsIDCheckedlistbox.Items.Count; i++)
{
if (_SelectedDoctorsChecked.Contains(DoctorsIDCheckedlistbox.Items[i].ToString()))
{
try
{
DoctorsIDCheckedlistbox.SetItemChecked(i, true);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
I期望上面的代码通过 _SelectedDoctorsChecked
列表进行查找,该列表将选择医生,并在医生的专业复选框状态更改时对其进行检查。但这不起作用。
I expect code above look through _SelectedDoctorsChecked
list which is selected doctors and check them when doctors' specialty checkboxes status changes. But it don't work.
例如:
我在医生的专长中打了A,并且项目1、2和3会显示在医生的名字中。我检查1和3。当我在医生专业中检查B时,将显示A中的项目1、2和3以及B中的4、5和6。我希望检查1号和3号。
Example:
I check A in doctors' specialty and items 1, 2 and 3 will be shown in doctors' name. I check 1 and 3. When I check B in doctors' specialty, Items 1, 2 and 3 from A and 4, 5 and 6 from B will be shown. I expect number 1 and 3 be checked. But it won't.
编辑:
我的 Checkedlistbox
控制数据源:
DoctorsIDCheckedlistbox.DataSource = _ClinicEntities.Tbl_Doctors
.Where(w => _SelectedSpecialty.Contains(w.SpecialtyID))
.Select(s => new DoctorListCheckbox{ Name = s.Name + " " + s.LastName, DoctorID = s.DoctorID })
.ToList();
DoctorsIDCheckedlistbox.DisplayMember = "Name";
DoctorsIDCheckedlistbox.ValueMember = "DoctorID";
和 DoctorListCheckbox
类:
public partial class DoctorListCheckbox
{
public int DoctorID { get; set; }
public string Name { get; set; }
public CheckState CheckState { get; set; }
public override string ToString()
{
return Name;
}
}
我已经基于 Microsoft示例
推荐答案
基本知识与我在数据源中的更新会重置CheckedListBox复选框。
您需要定义一个 BindingList< Specialties>
作为特殊性选中列表框的数据源,并显示所有特殊性
You need to define a BindingList<Specialties>
as data source of the specialties checked list box and show all specialties.
对于医生来说,您需要一个空的 BindingList< CheckedListBoxItem< Doctor>>
并将其设置为数据源医生检查列表框。然后,您需要处理以下事件:
For doctors, you need an empty BindingList<CheckedListBoxItem<Doctor>>
and set it as data source of doctors checked list box. Then you need to handle the following events:
-
ItemChecked
事件特殊检查列表框:如果该项目被选中,则从您的存储库中查找所有具有特殊检查的医生,并将其作为CheckedListBoxItem< Doctor>
到绑定列表。否则,请在绑定源中找到所有具有未检查专科的医生并将其删除。
ItemChecked
event of specialties checked list box: If the item is checked, then find all doctors with the checked specialty from your repository and them asCheckedListBoxItem<Doctor>
to the binding list. Otherwise, find all doctors with unchecked specialty in the binding source and remove them.
ItemChecked
事件医生:使用已检查列表框项目的检查状态来同步绑定列表项目的检查状态。
ItemChecked
event of doctors: Sync check state of the binding list item using the check state of checked list box item.
ListChanged
绑定列表的事件:使用绑定列表项目的检查状态同步选中列表框项目的检查状态。
ListChanged
event of the binding list: Sync the checked list box items check states, using the check state of the binding list items.
这里是一个完整示例,该示例具有两个已选中的专科和医生列表框,并根据所选专科选择医生:
Here is the full example for a scenario of having 2 checked list box of specialties and doctors and select doctors based on the selected specialties:
模型
public class Speciality
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() { return Name; }
}
public class Doctor
{
public int Id { get; set; }
public string Name { get; set; }
public int SpecialityId { get; set; }
public override string ToString() { return Name; }
}
public class CheckedListBoxItem<T>
{
public CheckedListBoxItem(T item)
{
DataBoundItem = item;
}
public T DataBoundItem { get; set; }
public CheckState CheckState { get; set; }
public override string ToString() { return DataBoundItem.ToString(); }
}
样本数据
public class DB
{
public IEnumerable<Speciality> Specialities
{
get
{
return new List<Speciality>()
{
new Speciality(){ Id= 1, Name ="S1"},
new Speciality(){ Id= 2, Name ="S2"},
new Speciality(){ Id= 3, Name ="S3"},
};
}
}
public IEnumerable<Doctor> Doctors
{
get
{
return new List<Doctor>()
{
new Doctor(){ Id= 1, Name ="D1", SpecialityId = 1},
new Doctor(){ Id= 2, Name ="D2", SpecialityId = 2},
new Doctor(){ Id= 3, Name ="D3", SpecialityId = 2},
new Doctor(){ Id= 4, Name ="D4", SpecialityId = 3},
new Doctor(){ Id= 5, Name ="D5", SpecialityId = 3},
new Doctor(){ Id= 6, Name ="D6", SpecialityId = 3},
};
}
}
}
表单事件处理程序
DB db = new DB();
BindingList<Speciality> specialities;
BindingList<CheckedListBoxItem<Doctor>> doctors;
private void Form10_Load(object sender, System.EventArgs e)
{
specialities = new BindingList<Speciality>(db.Specialities.ToList());
specialitiesCheckedListBox.DataSource = specialities;
doctors = new BindingList<CheckedListBoxItem<Doctor>>();
doctorsCheckedListBox.DataSource = doctors;
doctors.ListChanged += doctors_ListChanged;
}
private void doctors_ListChanged(object sender, ListChangedEventArgs e)
{
for (var i = 0; i < doctorsCheckedListBox.Items.Count; i++) {
doctorsCheckedListBox.SetItemCheckState(i,
((CheckedListBoxItem<Doctor>)doctorsCheckedListBox.Items[i]).CheckState);
}
}
private void specialitiesCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
{
var item = (Speciality)specialitiesCheckedListBox.Items[e.Index];
if (e.NewValue == CheckState.Checked) {
db.Doctors.Where(x => x.SpecialityId == item.Id)
.Select(x => new CheckedListBoxItem<Doctor>(x)).ToList()
.ForEach(x => doctors.Add(x));
}
else {
doctors.Where(x => x.DataBoundItem.SpecialityId == item.Id)
.ToList().ForEach(x => doctors.Remove(x));
}
}
private void doctorsCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
{
((CheckedListBoxItem<Doctor>)doctorsCheckedListBox.Items[e.Index])
.CheckState = e.NewValue;
}
这篇关于保留级联CheckedListBox中项目的检查状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!