/// <summary> /// Updates a CheckedListBox based on items in a folder and a dictionary. Also updates the dictonary. /// </summary> /// <param name="clb">CheckedListBox to update</param> /// <param name="checked_items">Dictionary containing checked/unchecked items</param> /// <param name="folder_path">Path to query files from</param> /// <param name="filter_string">Only filenames matching the filter_string are added</param> /// <param name="only_show_chosen">Only show files which are ticked</param> private void UpdateChosenList(CheckedListBox clb, Dictionary <string, bool> checked_items, string folder_path, string filter_string, bool only_show_chosen) { clb.Enabled = false; clb.Hide(); string[] files = Directory.GetFiles(folder_path); int old_index = clb.SelectedIndex; string old_item = ""; string old_top_item = ""; if (clb.SelectedItem != null) { old_item = clb.SelectedItem.ToString(); } if (clb.Items.Count != 0) { old_top_item = clb.Items[clb.TopIndex].ToString(); } clb.Items.Clear(); List <string> filtered_filenames = new List <string>(); //Filter queried files if (filter_string != "") { foreach (string file in files) { if (file.ToLower().Contains(filter_string.ToLower())) { filtered_filenames.Add(file); } } } else { filtered_filenames.AddRange(files); } // We change the selected index here without wanting to fire the event handler again dont_update_list = true; int new_top_index = 0; //For each item, add the checked state if found in Dictionary foreach (string file in filtered_filenames) { string file_split = file.Split('\\')[1]; if (checked_items.ContainsKey(file_split)) { if (only_show_chosen) { if (checked_items[file_split] == true) { clb.Items.Add(file_split, checked_items[file_split]); if (file_split == old_item) { clb.SelectedIndex = clb.Items.Count - 1; } if (file_split == old_top_item) { new_top_index = clb.Items.Count - 1; } } } else { clb.Items.Add(file_split, checked_items[file_split]); if (file_split == old_item) { clb.SelectedIndex = clb.Items.Count - 1; } if (file_split == old_top_item) { new_top_index = clb.Items.Count - 1; } } } else { //Dictionary entry is not there -> file is new. Add entry checked_items.Add(file_split, false); if (only_show_chosen == false) { clb.Items.Add(file_split, false); } } } // clb.Update(); dont_update_list = true; clb.TopIndex = new_top_index; dont_update_list = false; clb.Enabled = true; clb.Show(); }
/// <summary> /// 打开选项列表,刷新下来菜单 /// </summary> /// <param name="e"></param> protected override void OnDropDown(EventArgs e) { if (lst.Items.Count == 0) { // 假如数据还没有加载 // 那么加载. lst.BeginUpdate(); for (int i = 0; i < this.CheckAbleItemList.Count; i++) { lst.Items.Add(this.CheckAbleItemList[i]); } lst.EndUpdate(); lst.ItemHeight = this.ItemHeight; lst.BorderStyle = BorderStyle.FixedSingle; lst.Size = new Size(this.DropDownWidth, this.ItemHeight * (this.MaxDropDownItems - 1) - (int)this.ItemHeight / 2); lst.Location = new Point(this.Left, this.Top + this.ItemHeight + 6); this.Parent.Controls.Add(lst); // 加这句话的目的, 是为了避免 控件被别的控件挡住. lst.BringToFront(); } if (lstShowFlag == CheckedListBoxShowMode.Hide) { // 当前未显示,调整为显示. lst.Show(); lst.Focus(); lstShowFlag = CheckedListBoxShowMode.Show; } else if (lstShowFlag == CheckedListBoxShowMode.Show) { // 当前已显示,调整为不显示. lst.Hide(); lstShowFlag = CheckedListBoxShowMode.Hide; } else if (lstShowFlag == CheckedListBoxShowMode.LostFocus) { // 当前是 CheckedListBox 失去输入焦点. // 对于失去焦点的情况. // 需要作判断 // 因为 可能是点到其它的控件,而 CheckedListBox 失去输入焦点. // 也可能是 直接从 CheckedListBox 点到本控件. if (DateTime.Now.AddMilliseconds(-250) > lastLostFocusDateTime) { // 如果 CheckedListBox 失去焦点的时间 // 与本次点击下拉列表的时间 // 间隔超过 250 毫秒 // 认为是 经过了另外一个控件. // 现在点击回来了,需要显示. lst.Show(); lst.Focus(); lstShowFlag = CheckedListBoxShowMode.Show; } else { // 是直接从 CheckedListBox 失去焦点 // 然后再点击了 本 ComboBox 控件. lstShowFlag = CheckedListBoxShowMode.Hide; } } }