using NaiBa.Util.Extension; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using TemuKJD.Extension; namespace TemuKJD.UserComponent { public partial class UcComboBoxMutiSelect : ComboBox { //private bool _IsMultiSelect; //public bool IsMultiSelect { get => _IsMultiSelect; set => _IsMultiSelect = value; } public string DefaultText { get; set; } = "全部"; public List SelectItems { get { if (this.checkedListBox == null) return this.Items.Cast().ToList(); List lstObj = new List(); for (int i = 0; i < checkedListBox.Items.Count; i++) { if (checkedListBox.GetItemChecked(i)) { lstObj.Add(checkedListBox.Items[i]); } } return lstObj; } } CheckedListBox checkedListBox = null; public UcComboBoxMutiSelect() { SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); UpdateStyles(); this.Text = DefaultText; this.DropDownWidth = 1; this.DropDownHeight = 1; this.DropDown += UcComboBoxMutiSelect_DropDown; this.DropDownClosed += UcComboBoxMutiSelect_DropDownClosed; } private void UcComboBoxMutiSelect_DropDownClosed(object sender, EventArgs e) { if (checkedListBox != null) { var parentForm = this.FindForm(); Point mousePosition = parentForm.PointToClient(Cursor.Position); Point relativeLocation = checkedListBox.GetRelativePosition(); if (mousePosition.X < relativeLocation.X || mousePosition.X > relativeLocation.X + checkedListBox.Width || mousePosition.Y < relativeLocation.Y || mousePosition.Y > relativeLocation.Y + checkedListBox.Height) { checkedListBox.Visible = false; } } } private void UcComboBoxMutiSelect_DropDown(object sender, EventArgs e) { var parentForm = this.FindForm(); if (checkedListBox == null) { checkedListBox = new CheckedListBox(); checkedListBox.Visible = false; checkedListBox.CheckOnClick = true; checkedListBox.ItemCheck += checkedListBox_ItemCheck; checkedListBox.MouseLeave += checkedListBox_MouseLeave; checkedListBox.MouseEnter += CheckedListBox_MouseEnter; checkedListBox.MouseMove += CheckedListBox_MouseMove; //checkedListBox.MouseUp += new MouseEventHandler(checkedListBox_MouseUp); parentForm.Controls.Add(checkedListBox); } string str1 = string.Join(",", this.Items.Cast().Select(o => o.ParseToString())); string str2 = string.Join(",", this.checkedListBox.Items.Cast().Select(o => o.ParseToString())); if (str1 != str2) { checkedListBox.Items.Clear(); foreach (var item in this.Items) { checkedListBox.Items.Add(item.ParseToString(), true); } } for (int index = 0; index < checkedListBox.Items.Count; index++) { var item = checkedListBox.Items[index]; if (this.Text == "全部" || this.Text.Split(new string[] { ";", ";", ",", "," }, StringSplitOptions.RemoveEmptyEntries).Contains(item.ParseToString())) checkedListBox.SetItemChecked(index, true); else checkedListBox.SetItemChecked(index, false); } // 计算宽度 int maxItemWidth = 0; for (int index = 0; index < checkedListBox.Items.Count; index++) { var wth = TextRenderer.MeasureText(checkedListBox.Items[index].ToString(), checkedListBox.Font).Width + 20; if (wth > maxItemWidth) maxItemWidth = wth; } checkedListBox.SendToBack(); checkedListBox.Visible = true; // 确定弹出列表框的大小和位置 //checkedListBox.Size = new Size(Math.Max(80, this.Width), Math.Min(300, checkedListBox.PreferredHeight)); checkedListBox.Size = new Size(Math.Max(this.Width, maxItemWidth), Math.Min(300, checkedListBox.PreferredHeight)); Point relativeLocation = this.GetRelativePosition(); if (parentForm.Height - relativeLocation.Y >= this.Height + checkedListBox.Size.Height + 20) relativeLocation = new Point(relativeLocation.X, relativeLocation.Y + this.Height); else relativeLocation = new Point(relativeLocation.X, relativeLocation.Y - checkedListBox.Size.Height); checkedListBox.Location = relativeLocation; checkedListBox.BringToFront(); //parentForm.ActiveControl = checkedListBox; //checkedListBox.Focus(); } private void CheckedListBox_MouseMove(object sender, MouseEventArgs e) { //this.DropDownClosed -= UcComboBoxMutiSelect_DropDownClosed; } private void CheckedListBox_MouseEnter(object sender, EventArgs e) { //this.DropDownClosed -= UcComboBoxMutiSelect_DropDownClosed; } private void checkedListBox_MouseLeave(object sender, EventArgs e) { ////this.DropDownClosed += UcComboBoxMutiSelect_DropDownClosed; ////统计选取的项目 //string str = ""; //for (int i = 0; i < checkedListBox.Items.Count; i++) //{ // if (checkedListBox.GetItemChecked(i)) // { // str += $"{checkedListBox.Items[i].ParseToString()};"; // } //} //this.Text = str; checkedListBox.Visible = false; this.OnDropDownClosed(null); } private void checkedListBox_ItemCheck(object sender, EventArgs e) { //统计选取的项目 Task.Run(() => { Thread.Sleep(100); Invoke(new Action(() => { string str = ""; for (int i = 0; i < checkedListBox.Items.Count; i++) { if (checkedListBox.GetItemChecked(i)) { str += $"{checkedListBox.Items[i].ParseToString()};"; } } this.Text = str; string str1 = string.Join(";", this.Items.Cast().Select(o => o.ParseToString())); if (this.Text.Trim(';') == str1) { this.Text = this.DefaultText; } })); }); } } }