checkedlistbox控件也是我們常用的控件,我們仿照上一篇checkbox的例程,這回用checkedlistbox來實現
本來以爲是很容易實現的,結果發現想讓功能做的完善以下,中間有許多坑需要填,下面我們一起來看一下吧
1.界面佈局
界面佈局如下
具體的佈局代碼就不貼了,總之就是在在上一篇的基礎上使用checkedlistbox來實現全選,並新增了刪除和添加的功能
2.用法示例
需要注意的有這麼幾點
1.事件順序
當我們點擊某一項的時候,checkedlistbox調用事件的順序是這樣的
ItemCheck -> SelectedValueChanged -> SelectedIndexChanged
2.點擊空白
如上圖所示,當我們已經選中一項的時候,再點擊空白處,這一項的狀態依然會改變,避免的方法可以參考這篇博文
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 = "";
}
}
}
}
不足之處希望能多批評指正,謝謝