问题
I have asked This Question a few days ago and the answer has solved my problem perfectly. I have another related question to my own post.
The CheckState
of second (Doctors') Checkedlistbox
items will be saved when I change data source by checking the first (Specialty) Checkedlistbox
items. Here's my code:
CheckedListBoxItem
class:
/// <summary>
/// A class to svae status of checkboxes when datasource changes.
/// </summary>
/// <typeparam name="T"></typeparam>
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(); }
}
SpecialityCheckList
and DoctorCheckList
related to first and second Checkedlistbox
controls:
public class SpecialityCheckList
{
public int SpecialtyID { get; set; }
public string Title { get; set; }
public override string ToString() { return Title; }
}
public class DoctorCheckList
{
public int DoctorID { get; set; }
public string Name { get; set; }
public int? SpecialityId { get; set; }
public override string ToString() { return Name; }
}
Form codes:
BindingList<CheckedListBoxItem<DoctorCheckList>> doctors = new BindingList<CheckedListBoxItem<DoctorCheckList>>();
private void ReportVisitSocialInsurance_Load(object sender, EventArgs e)
{
SpecialtyTypeCheckbox.DataSource = new BindingList<SpecialityCheckList>(_Specialty.SelectTbl_SpecialityCheckListBox());
DoctorsIDCheckedlistbox.DataSource = doctors;
doctors.ListChanged += Doctors_ListChanged;
}
private void Doctors_ListChanged(object sender, ListChangedEventArgs e)
{
for (var i = 0; i < DoctorsIDCheckedlistbox.Items.Count; i++)
{
DoctorsIDCheckedlistbox.SetItemCheckState(i, ((CheckedListBoxItem<DoctorCheckList>)DoctorsIDCheckedlistbox.Items[i]).CheckState);
}
}
private void SpecialtyTypeID_ItemCheck(object sender, ItemCheckEventArgs e)
{
var item = (SpecialityCheckList)SpecialtyTypeCheckbox.Items[e.Index];
if (e.NewValue == CheckState.Checked)
{
_Doctors.SelectTbl_DoctorsCheckListBox(item.SpecialtyID)
.Select(s => new CheckedListBoxItem<DoctorCheckList>(s)).ToList()
.ForEach(f => doctors.Add(f));
} else {
doctors
.Where(w => w.DataBoundItem.SpecialityId == item.SpecialtyID)
.ToList()
.ForEach(f => doctors.Remove(f));
}
}
private void DoctorsID_ItemCheck(object sender, ItemCheckEventArgs e)
{
((CheckedListBoxItem<DoctorCheckList>)DoctorsIDCheckedlistbox.Items[e.Index]).CheckState = e.NewValue;
}
How ever if I search through Doctors' Checkedlistbox
items and check a item, when I clear search textbox to see all doctors' name the checked item is different from what I have checked while searching. This is because it uses index I think. Here is my code when searching:
private void DoctorsNameTextbox_TextChanged(object sender, EventArgs e)
{
BindingList<CheckedListBoxItem<DoctorCheckList>> doctorsSerach =
ObjectCloning.CloneJson<BindingList<CheckedListBoxItem<DoctorCheckList>>>(doctors);
doctorsSerach
.Where(w => !w.DataBoundItem.Name.Contains(DoctorsNameTextbox.Text))
.ToList()
.ForEach(f => doctorsSerach.Remove(f));
DoctorsIDCheckedlistbox.DataSource = doctorsSerach;
}
The problem is that for example if I search for name Ali, it shows me 3 items. When I check item number 2nd and clear search textbox, item at index 1 (zero-based) has been checked.
回答1:
When handling TexctChanged
event of the searchTextBox
, you can check if the text is empty, set the data source to list of doctors, otherwise set the data source to a list of filtered doctors. In both case, after setting the data source, sync the check marks with data source:
private void searchTextBox_TextChanged(object sender, EventArgs e)
{
if(string.IsNullOrEmpty(searchTextBox.Text))
{
doctorsCheckedListBox.DataSource = doctors;
}
else
{
var filteredDoctors =
new BindingList<CheckedListBoxItem<Doctor>>
(doctors.Where(x => x.DataBoundItem.Name.StartsWith(searchTextBox.Text))
.ToList());
doctorsCheckedListBox.DataSource = filteredDoctors;
}
for (var i = 0; i < doctorsCheckedListBox.Items.Count; i++)
{
doctorsCheckedListBox.SetItemCheckState(i,
((CheckedListBoxItem<Doctor>)doctorsCheckedListBox.Items[i]).CheckState);
}
}
来源:https://stackoverflow.com/questions/59232592/filter-cascading-checkedlistbox-and-preserve-check-state-of-the-items