새 상태에서 CheckedItems를 사용할 수 있도록 항목을 확인한 후 이벤트를 원하는 CheckedListBox가 있습니다.
CheckedItems가 업데이트되기 전에 ItemChecked가 실행되기 때문에 즉시 작동하지 않습니다.
CheckedItems가 업데이트 될 때 알림을 받으려면 어떤 종류의 메서드 또는 이벤트를 사용할 수 있습니까?
답변
ItemCheck
클릭되는 항목의 새로운 상태를 확인하면 이벤트 를 사용할 수 있습니다 . 이벤트 인수에서 e.NewValue
. 경우에 NewValue
선택되어, 당신의 논리에 적절한 컬렉션과 함께 현재 항목을 포함한다 :
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
List<string> checkedItems = new List<string>();
foreach (var item in checkedListBox1.CheckedItems)
checkedItems.Add(item.ToString());
if (e.NewValue == CheckState.Checked)
checkedItems.Add(checkedListBox1.Items[e.Index].ToString());
else
checkedItems.Remove(checkedListBox1.Items[e.Index].ToString());
foreach (string item in checkedItems)
{
...
}
}
또 다른 예로,이 항목을 (un-) 체크 한 후 컬렉션이 비어 있는지 확인하려면 :
private void ListProjects_ItemCheck(object sender, ItemCheckEventArgs args)
{
if (ListProjects.CheckedItems.Count == 1 && args.NewValue == CheckState.Unchecked)
// The collection is about to be emptied: there's just one item checked, and it's being unchecked at this moment
...
else
// The collection will not be empty once this click is handled
...
}
답변
이것에 관한 많은 관련 StackOverflow 게시물이 있습니다 … Branimir의 솔루션 뿐만 아니라 다음 두 가지 더 간단한 것들이 있습니다.
ItemCheck에서 지연된 실행 ( 여기에도 있음 ) :
void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
this.BeginInvoke((MethodInvoker) (
() => Console.WriteLine(checkedListBox1.SelectedItems.Count)));
}
void checkedListBox1_MouseUp(object sender, MouseEventArgs e)
{
Console.WriteLine(checkedListBox1.SelectedItems.Count);
}
첫 번째 옵션을 선호합니다. 두 번째 옵션은 오 탐지 (예 : 너무 자주 실행 됨)를 초래하기 때문입니다.
답변
나는 이것을 시도했고 효과가 있었다.
private void clbOrg_ItemCheck(object sender, ItemCheckEventArgs e)
{
CheckedListBox clb = (CheckedListBox)sender;
// Switch off event handler
clb.ItemCheck -= clbOrg_ItemCheck;
clb.SetItemCheckState(e.Index, e.NewValue);
// Switch on event handler
clb.ItemCheck += clbOrg_ItemCheck;
// Now you can go further
CallExternalRoutine();
}
답변
파생 CheckedListBox
및 구현
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.CheckedListBox.ItemCheck"/> event.
/// </summary>
/// <param name="ice">An <see cref="T:System.Windows.Forms.ItemCheckEventArgs"/> that contains the event data.
/// </param>
protected override void OnItemCheck(ItemCheckEventArgs e)
{
base.OnItemCheck(e);
EventHandler handler = AfterItemCheck;
if (handler != null)
{
Delegate[] invocationList = AfterItemCheck.GetInvocationList();
foreach (var receiver in invocationList)
{
AfterItemCheck -= (EventHandler) receiver;
}
SetItemCheckState(e.Index, e.NewValue);
foreach (var receiver in invocationList)
{
AfterItemCheck += (EventHandler) receiver;
}
}
OnAfterItemCheck(EventArgs.Empty);
}
public event EventHandler AfterItemCheck;
public void OnAfterItemCheck(EventArgs e)
{
EventHandler handler = AfterItemCheck;
if (handler != null)
handler(this, e);
}
답변
답변
몇 가지 테스트 후 ItemCheck 이벤트 후에 SelectedIndexChanged 이벤트가 트리거되는 것을 볼 수 있습니다. 속성 CheckOnClick True 유지
최고의 코딩
답변
이것은 작동하지만 얼마나 우아한 지 확실하지 않습니다!
Private Sub chkFilters_Changed(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkFilters.ItemCheck
Static Updating As Boolean
If Updating Then Exit Sub
Updating = True
Dim cmbBox As CheckedListBox = sender
Dim Item As ItemCheckEventArgs = e
If Item.NewValue = CheckState.Checked Then
cmbBox.SetItemChecked(Item.Index, True)
Else
cmbBox.SetItemChecked(Item.Index, False)
End If
'Do something with the updated checked box
Call LoadListData(Me, False)
Updating = False
End Sub