winform控件之checkedListBox

checkedlistbox控件也是我们常用的控件,我们仿照上一篇checkbox的例程,这回用checkedlistbox来实现

本来以为是很容易实现的,结果发现想让功能做的完善以下,中间有许多坑需要填,下面我们一起来看一下吧

 

1.界面布局

界面布局如下

winform控件之checkedListBox_第1张图片

具体的布局代码就不贴了,总之就是在在上一篇的基础上使用checkedlistbox来实现全选,并新增了删除和添加的功能

 

2.用法示例

需要注意的有这么几点

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 = "";
            }
        }
    }
}

 

 

不足之处希望能多批评指正,谢谢

你可能感兴趣的:(winform)