ListView控件有一个 ItemCheck 事件,该事件在项目更改之前触发,并且 ItemChecked 事件在之后触发 项目更改。有关详细信息,请参阅this SO question。
CheckedListBox控件只有ItemCheck事件。
使用CheckedListBox执行此类操作的最佳方法是什么?
private void checkedListBox_ItemChecked(object sender ItemCheckedEventArgs e)
{
okButton.Enabled = (checkedListBox.CheckedItems.Count > 0);
}
补充问题: 为什么没有CheckedListBox.ItemChecked事件?
答案 0 :(得分:51)
处理引发时无法处理的事件的一个很好的技巧是延迟处理。您可以使用Control.BeginInvoke()方法执行此操作,只要调度所有事件,副作用完成并且UI线程再次空闲,它就会运行。通常也有助于TreeView,另一个胡思乱想的控件。
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
this.BeginInvoke((MethodInvoker)delegate {
okButton.Enabled = checkedListBox1.CheckedItems.Count > 0;
});
}
以防万一:这与线程无关,而且技巧很便宜。
为什么没有ItemChecked事件?不太确定。 CheckedListBox只是一个非常好的控件。绝对不是原始Winforms团队中的一位大师所做的。
答案 1 :(得分:4)
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
int count = this.checkedListBox1.CheckedItems.Count;
if (e.CurrentValue != CheckState.Checked && e.NewValue == CheckState.Checked) {
count += 1;
} else if (e.CurrentValue == CheckState.Checked && e.NewValue != CheckState.Checked) {
count -= 1;
}
this.okButton.Enabled = count > 0;
}
答案 2 :(得分:1)
基于Hans Passant's answer我正在添加一个通用的VB.NET版本。我需要一个方法,可以在窗体上调用所有CheckedListBox控件。如果您需要为每个控件使用单独的方法,则可以轻松调整此项(尽管添加了一些冗余)。
Public Class Form1
Delegate Sub ProcessItemCheck(ByRef ListBoxObject As CheckedListBox)
Private Sub ProcessItemCheckSub(ByRef ListBoxObject As CheckedListBox)
' Do your actual ItemCheck stuff here
End Sub
Private Sub CheckedListBox1_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
Dim Objects As Object() = {CheckedListBox1}
BeginInvoke(New ProcessItemCheck(AddressOf ProcessItemCheckSub), Objects)
End Sub
End Class
答案 3 :(得分:0)
我使用Timer来解决这个问题。通过ItemCheck事件启用计时器。在Timer的Tick事件中采取行动。
无论是通过鼠标单击还是按空格键检查项目,都可以使用此功能。我们将利用刚检查(或未检查)的项目始终是选定项目的事实。
定时器的间隔可以低至1.当Tick事件被提升时,将设置新的Checked状态。
这个VB.NET代码显示了这个概念。您可以使用许多变体。您可能希望增加计时器的间隔,以允许用户在采取措施之前更改多个项目的检查状态。然后在Tick事件中,顺序传递所有
列表中的项目或使用其CheckedItems集合采取适当的措施。
这就是为什么我们首先在ItemCheck事件中禁用Timer。禁用然后启用会导致间隔期重新启动。
Private Sub ckl_ItemCheck(ByVal sender As Object, _
ByVal e As System.Windows.Forms.ItemCheckEventArgs) _
Handles ckl.ItemCheck
tmr.Enabled = False
tmr.Enabled = True
End Sub
Private Sub tmr_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles tmr.Tick
tmr.Enabled = False
Debug.Write(ckl.SelectedIndex)
Debug.Write(": ")
Debug.WriteLine(ckl.GetItemChecked(ckl.SelectedIndex).ToString)
End Sub