2 回答
TA贡献1817条经验 获得超6个赞
您需要自己跟踪检查状态。
作为一个选项,您可以为包含文本和检查状态的项目创建模型类。然后在ItemCheck
控制事件中,设置项目模型的检查状态值。另外,ListChenged
如果您BindingList<T>
刷新检查项目状态。
例子
创建CheckedListBoxItem
类:
public class CheckedListBoxItem
{
public CheckedListBoxItem(string text)
{
Text = text;
}
public string Text { get; set; }
public CheckState CheckState { get; set; }
public override string ToString()
{
return Text;
}
}
设置CheckedListBox如下:
private BindingList<CheckedListBoxItem> list = new BindingList<CheckedListBoxItem>();
private void Form1_Load(object sender, EventArgs e)
{
list.Add(new CheckedListBoxItem("A"));
list.Add(new CheckedListBoxItem("B"));
list.Add(new CheckedListBoxItem("C"));
list.Add(new CheckedListBoxItem("D"));
checkedListBox1.DataSource = list;
checkedListBox1.ItemCheck += CheckedListBox1_ItemCheck;
list.ListChanged += List_ListChanged;
}
private void CheckedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
((CheckedListBoxItem)checkedListBox1.Items[e.Index]).CheckState = e.NewValue;
}
private void List_ListChanged(object sender, ListChangedEventArgs e)
{
for (var i = 0; i < checkedListBox1.Items.Count; i++)
{
checkedListBox1.SetItemCheckState(i,
((CheckedListBoxItem)checkedListBox1.Items[i]).CheckState);
}
}
TA贡献1802条经验 获得超4个赞
另一种方法。它不需要自定义类的支持(尽量不这样做)。
由于在这种情况下,基础项目列表是非托管的(在其他地方托管),因此必须手动处理项目的检查状态。
有趣的是,查看在列表中添加或删除项目时引发的事件的顺序是什么BindingList
(例如,在列表更新之前没有通知列表更改的事件,ListChangedEventArgs.OldIndex
从未设置,因此始终-1
等)。 )。
由于 CheckedListBox 的来源很简单List<string>
,因此当列表更新时,ItemCheckState
会丢失。因此,需要存储这些状态并在需要时重新应用,调用SetItemCheckedState方法。
由于必须调整项目的状态以匹配新的列表组成(在删除或插入项目之后)并且此过程是同步的,因此事件ItemCheck
(用于更新所有项目CheckState
)会异常引发并需要延迟执行。这就是为什么BeginInvoke()
这里使用的原因。
总而言之,在内部存储这些状态的专用类对象是正确的选择。在这里,绑定由于缺乏基类的支持而受到影响。并不是说它在任何地方都另有说明: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();
}
- 2 回答
- 0 关注
- 123 浏览
添加回答
举报