Другой метод. Он не требует поддержки пользовательского класса (пытается этого не делать).
Поскольку базовый список элементов в данном случае неуправляемый (управляется где-то еще), состояние проверенных элементов должно обрабатываться вручную.
Это может быть интересно. чтобы увидеть, какова последовательность событий, возникающих при добавлении или удалении элемента из BindingList
(например, нет событий, уведомляющих об изменении списка до его обновления, ListChangedEventArgs.OldIndex
никогда не устанавливается, поэтому всегда -1
и т. д.) .
Поскольку источником CheckedListBox является простой List<string>
, при обновлении списка CheckState
элемента теряется. Следовательно, эти состояния необходимо сохранять и повторно применять при необходимости, вызывая SetItemCheckedState.
Поскольку состояние элементов должно быть скорректировано в соответствии с новой композицией списка (после того, как элемент был удален или вставлен), и эта процедура является синхронной, событие ItemCheck
(используемое для обновления всех элементов CheckState
) вызывается нестандартно и требует отложенного выполнения. . Вот почему здесь используется BeginInvoke()
.
В общем, специализированный объект класса, который хранит эти состояния внутри, как показано в Reza Aghaei answer, — это путь. . Здесь связывание страдает от отсутствия поддержки в базовых классах. Не то, чтобы где-то было указано иное: например, CheckedListBox.DataSource
даже не просматривается.
private BindingList<string> clbItemsList = new BindingList<string>();
public MyForm()
{
InitializeComponent();
clbItemsList.Add("A");
// (...)
checkedListBox1.DataSource = clbItemsList;
clbItemsList.ListChanged += this.clbListChanged;
checkedListBox1.ItemCheck += (s, e) => { BeginInvoke(new Action(()=> CheckedStateCurrent())); };
}
private void clbListChanged(object sender, ListChangedEventArgs e)
{
foreach (var item in clbCheckedItems.ToArray()) {
if (e.ListChangedType == ListChangedType.ItemAdded) {
checkedListBox1.SetItemCheckState(item.Index >= e.NewIndex ? item.Index + 1 : item.Index, item.State);
}
if (e.ListChangedType == ListChangedType.ItemDeleted) {
if (item.Index == e.NewIndex) {
clbCheckedItems.Remove(item);
continue;
}
checkedListBox1.SetItemCheckState(item.Index > e.NewIndex ? item.Index - 1 : item.Index, item.State);
}
}
}
private List<(CheckState State, int Index)> clbCheckedItems = new List<(CheckState State, int Index)>();
private void CheckedStateCurrent()
{
clbCheckedItems = checkedListBox1.CheckedIndices.OfType<int>()
.Select(item => (checkedListBox1.GetItemCheckState(item), item)).ToList();
}
person
Jimi
schedule
22.08.2019