亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

數據源中的更新重置 CheckedListBox 復選框

數據源中的更新重置 CheckedListBox 復選框

C#
蝴蝶刀刀 2023-09-16 17:26:45
我有一個 CheckedListBox,綁定到 BindingList:private BindingList<string> list = new BindingList<string>();public MyForm(){    InitializeComponent();    list.Add("A");    list.Add("B");    list.Add("C");    list.Add("D");    checkedListBox.DataSource = collection;}單擊某個按鈕時,列表會更新:private void Button_Click(object sender, EventArgs e){    list.Insert(0, "Hello!");}它工作正常,CheckedListBox 已更新。但是,當選中某些項目時,單擊該按鈕不僅會更新列表,還會將所有項目重置為取消選中。我該如何解決這個問題?
查看完整描述

2 回答

?
慕的地6264312

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);

? ? }

}


查看完整回答
反對 回復 2023-09-16
?
慕虎7371278

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();

}


查看完整回答
反對 回復 2023-09-16
  • 2 回答
  • 0 關注
  • 166 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號