checkedlistbox控件也是我们常用的控件,我们仿照上一篇checkbox的例程,这回用checkedlistbox来实现
本来以为是很容易实现的,结果发现想让功能做的完善以下,中间有许多坑需要填,下面我们一起来看一下吧
界面布局如下
具体的布局代码就不贴了,总之就是在在上一篇的基础上使用checkedlistbox来实现全选,并新增了删除和添加的功能
需要注意的有这么几点
1.事件顺序
当我们点击某一项的时候,checkedlistbox调用事件的顺序是这样的
ItemCheck -> SelectedValueChanged -> SelectedIndexChanged
2.点击空白
如上图所示,当我们已经选中一项的时候,再点击空白处,这一项的状态依然会改变,避免的方法可以参考这篇博文
CheckedListBox 当中项的状态改变
3.双击事件DoubleClick
如果我们某一项点击的比较快,会触发DoubleClick事件,这时候全选框状态和是否全选的状态会不一致,我们需要在这个事件里面重新进行检测
4.全选框状态
如上一篇CheckBox所述,全选按钮只能在Click事件里面进行处理,否则会出现事件嵌套
当我们点击全选按钮的时候,checkedlistbox会检测到我们点击的是空白,但是这时候我们检测全选框状态的时候,其状态并未改变,导致我们无法区分是点击了空白还是点击了全选框,所以只能单独设置个变量来判断是否点击了全选按钮
实现的时候遇到的问题基本上就是上面几条,大家可以自己实现下,因该会遇到不少问题,下面来看看具体的实现代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class FormMain : Form
{
public FormMain(ArrayList arrip_list)
{
InitializeComponent();
}
private void buttonShow_Click(object sender, EventArgs e)
{
string sb = "您的兴趣爱好是 ";
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
if (checkedListBox1.GetItemChecked(i) == true)
{
sb = sb + checkedListBox1.GetItemText(checkedListBox1.Items[i]) + ",";
}
}
label2.Text = "" + sb;
}
private void checkedListBox1_SelectedValueChanged(object sender, EventArgs e)
{
CheckedListBox clb = sender as CheckedListBox;
////点击空白处会触发该事件,如果之前没有选中任何项,则index为-1
if (clb.SelectedIndex != -1)
{
int SelectCount = 0;
if (bIsSelectAll == false && clb.GetItemChecked(clb.SelectedIndex) == true)
{
for (int i = 0; i < clb.Items.Count; i++)
{
if (clb.GetItemChecked(i) == true)
{
SelectCount++;
}
}
if (SelectCount == clb.Items.Count)
{
checkBoxSelectAll.CheckState = CheckState.Checked;
//Console.WriteLine("Checked");
}
}
else if (bIsSelectAll == false && clb.GetItemChecked(clb.SelectedIndex) == false)
{
checkBoxSelectAll.CheckState = CheckState.Unchecked;
//Console.WriteLine("UnChecked");
}
}
//Console.WriteLine("Value Changed");
//这里为了避免点击空白处依然会更改之前的选中项,每次都将index清空为-1
//clb.SelectedIndex = -1;
}
//这里单独个变量用于记录全选按钮是否按下
//如之前CheckBox所述,全选按钮只能在Click事件里面进行处理,否则会出现事件嵌套
//但是在Click事件里面的问题就是,在其他地方获取全选按钮的状态时候,状态并未改变
//导致在Checklistbox判断是点击空白还是点击全选的时候无法进行判断
private bool bIsSelectAll = false;
private void checkBoxSelectAll_Click(object sender, EventArgs e)
{
CheckBox cb = sender as CheckBox;
if (cb.CheckState == CheckState.Checked)
//if (checkBoxSelectAll.CheckState == CheckState.Checked)
{
bIsSelectAll = true;
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
//这里需要手动设置以下索引,否则在直接设置某项状态的时候
//SelectedItem是null
checkedListBox1.SelectedIndex = i;
checkedListBox1.SetItemChecked(i, true);
}
}
else if (cb.CheckState == CheckState.Unchecked)
{
bIsSelectAll = true;
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
//这里需要手动设置以下索引,否则在直接设置某项状态的时候
//SelectedItem是null
checkedListBox1.SelectedIndex = i;
checkedListBox1.SetItemChecked(i, false);
}
}
bIsSelectAll = false;
//这里清空下索引,否则每次点击后最后一项都会被选中
//清空索引后,让所有项都取消反蓝
checkedListBox1.SelectedIndex = -1;
}
private ArrayList listM_moteeui = new ArrayList();
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
CheckedListBox clb = sender as CheckedListBox;
//检测是否点击到空白的方法,可以参考下面这篇博文
//https://blog.csdn.net/apgk1/article/details/50787435
//判断如果点击的坐标是空白的地方则不更改值
if (bIsSelectAll == false && clb.IndexFromPoint(
clb.PointToClient(Cursor.Position).X,
clb.PointToClient(Cursor.Position).Y) == -1)
{
e.NewValue = e.CurrentValue;
}
else //这边开始判断集合当中是不是已经有ID,如果没有就加入
{
string temp = clb.SelectedItem.ToString();
if (!listM_moteeui.Contains(temp))
{
listM_moteeui.Add(temp);
}
else
{
listM_moteeui.Remove(temp);
}
}
}
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
CheckedListBox clb = sender as CheckedListBox;
}
private void checkedListBox1_DoubleClick(object sender, EventArgs e)
{
CheckedListBox clb = sender as CheckedListBox;
//这里需要在DoubleClick中重新判断以下,因为如果点击的太快
//DoubleClick事件触发,全选按钮和checklistbox的状态会不一致
if (clb.SelectedIndex != -1)
{
int SelectCount = 0;
if (clb.GetItemChecked(clb.SelectedIndex) == true)
{
for (int i = 0; i < clb.Items.Count; i++)
{
if (clb.GetItemChecked(i) == true)
{
SelectCount++;
}
}
if (SelectCount == clb.Items.Count)
{
checkBoxSelectAll.CheckState = CheckState.Checked;
}
}
else if (clb.GetItemChecked(clb.SelectedIndex) == false)
{
checkBoxSelectAll.CheckState = CheckState.Unchecked;
}
}
}
private void buttonDelete_Click(object sender, EventArgs e)
{
if (checkedListBox1.SelectedIndex != -1)
{
//删除选中项
checkedListBox1.Items.Remove(checkedListBox1.GetItemText(checkedListBox1.Items[checkedListBox1.SelectedIndex]));
//重新检查是否需要选中全选按钮
int SelectCount = 0;
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
if (checkedListBox1.GetItemChecked(i) == true)
{
SelectCount++;
}
}
if (SelectCount == checkedListBox1.Items.Count)
{
checkBoxSelectAll.CheckState = CheckState.Checked;
//Console.WriteLine("Checked");
}
else
{
checkBoxSelectAll.CheckState = CheckState.Unchecked;
}
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
//如果内容不为空
if (textBoxAdd.Text != "")
{
//添加新内容到checklistbox
checkedListBox1.Items.Add(textBoxAdd.Text);
//清空内容
textBoxAdd.Text = "";
}
}
}
}
不足之处希望能多批评指正,谢谢