基本信息
源码名称:标签流式布局ComboBox多选控件
源码大小:0.58M
文件格式:.rar
开发语言:C#
更新时间:2021-09-03
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍

标签流式布局ComboBox多选winfrom控件.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace UserControlLibrary
{
    public partial class UComboxMuti : UserControl
    {
        /// <summary>
        /// 弹出部分
        /// </summary>
        HsToolStripDropDown toolStripDropDown;
        public UComboxMuti()
        {
            InitializeComponent();
        }

        //用于模拟键盘输入
        [DllImport("user32.dll")]
        private static extern void keybd_event(
            byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

        //显示控件
        //Control Control;
        //下拉面板
        Panel panel;
        //删除中
        bool Deling = false;
        //绘制面板用变量
        //光标前一位置
        Point pPoint;
        //光标当前位置
        Point cPoint;
        //鼠标是否已按下
        bool _isMouseDown = false;

        //关闭下拉时光标是否在ComboBox上
        bool _isCursorOnPanl = false;
        bool _isEditState = false;


        #region 数据交互方法
        /// <summary>
        ///  显示选项列表
        /// </summary>
        /// <param name="dt">0列=ID,1列=文本</param>
        public void SetOptionItem(DataTable dt)
        {
            FreezeControl(this, true);
            int i = 0;
            int c = dt.Rows.Count;
            ToolStripItem[] toolItems = new ToolStripItem[c];
            foreach (DataRow dr in dt.Rows)
            {
                ToolStripLabel tsl = new ToolStripLabel();
                tsl.Name = dr[0].ToString();
                tsl.Text = dr[1].ToString();
                tsl.IsLink = true;
                toolItems[i] = tsl;
                i ;
            }
            OptionItem.Items.Clear();
            OptionItem.Items.AddRange(toolItems);
            FreezeControl(this, false);
        }
        /// <summary>
        /// 显示选择值
        /// </summary>
        /// <param name="dt">0列=ID,1列=文本</param>
        public void SetValueItem(DataTable dt)
        {
           FreezeControl(this, true);
            foreach (DataRow dr in dt.Rows)
            {
                UComboxMutiTag ut = new UComboxMutiTag();
                ut.TagIndex = dr[0].ToString();
                ut.TagText = dr[1].ToString();
                ut.DelClick = Tl_DelClick;
                ut.BackColor = Color.LightGreen;
                ut.UEnabled = false;
                flowLayoutPanel2.Controls.Add(ut);
            }
            FreezeControl(this, false);

        }
        /// <summary>
        /// 获取ItemID
        /// </summary>
        /// <returns></returns>
        public List<string> GetItemsId()
        {

            List<string> strs = new List<string>();
            foreach (Control item in flowLayoutPanel2.Controls)
            {
                if (item is UComboxMutiTag)
                {
                    strs.Add(((UComboxMutiTag)item).TagIndex);
                }
            }
            return strs;

        }



        #endregion

        #region 数据交互属性
        [Browsable(true), Category("UC属性"), Description("选定项目集合")]
        [TypeConverter(typeof(System.ComponentModel.CollectionConverter))]//指定编辑器特性
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]//设定序列化特性 

        public List<ValueItem> ValItems
        {
            get //获取项目信息
            {
                List<ValueItem> strs = new List<ValueItem>();
                foreach (Control item in flowLayoutPanel2.Controls)
                {
                    if (item is UComboxMutiTag)
                    {
                        ValueItem Vi = new ValueItem();
                        Vi.IndexID = ((UComboxMutiTag)item).TagIndex;
                        Vi.Title = ((UComboxMutiTag)item).TagText;
                        strs.Add(Vi);
                    }
                }
                return strs;
            }

            set //设置显示项目
            {
               FreezeControl(this, true);
                foreach (ValueItem item in value)
                {
                    UComboxMutiTag ut = new UComboxMutiTag();
                    ut.TagIndex = item.IndexID;
                    ut.TagText = item.Title;
                    ut.BackColor = Color.LightGreen;
                    ut.DelClick = Tl_DelClick;
                    ut.UEnabled = false;
                    flowLayoutPanel2.Controls.Add(ut);
                }
                FreezeControl(this, false);
                ;
            }


        }


        [Browsable(true), Category("UC属性"), Description("选项集合")]
        //[TypeConverter(typeof(System.ComponentModel.CollectionConverter))]//指定编辑器特性
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]//设定序列化特性 
        public ToolStripItemCollection OptItems
        {
            get
            {
                return OptionItem.Items;
            }

            set
            {
                int i = 0;
                int c = value.Count;
                ToolStripItem[] toolItems = new ToolStripItem[c];
                foreach (ToolStripItem item in value)
                {
                    toolItems[i] = item;
                    i ;
                }

                OptionItem.Items.Clear();
                OptionItem.Items.AddRange(toolItems);


            }
        }


        #endregion


        [Browsable(true), Category("UC属性"), Description("编辑状态")]       
        public bool UEnabled
        {
            get { return _isEditState; }
            set
            {
                _isEditState = value;

                //显示X号
                foreach (Control item in this.flowLayoutPanel2.Controls)
                {
                    if (item is UComboxMutiTag)
                    {
                        ((UComboxMutiTag)item).UEnabled = value;
                    }
                }

                if (value)
                {
                   
                        OpenPanl();
                } 
            }
        }

        [Browsable(false)]
        public Control Control { get; set; }
        [Browsable(false)]




        public UComboxMuti(IContainer container)
        {
            container.Add(this);

            InitializeComponent();

            //绘制下拉面板
            this.DrawPanel();
            this.Control = this.panel1;// control;
            this.Control.Location = new Point(0, 0);
            this.Control.Dock = DockStyle.Fill;
            this.Control.Parent = this.panel;

        }

       
        /// <summary>
        /// 点击事件
        /// </summary>
        protected override void OnMouseClick(MouseEventArgs e)
        {
            this.Focus();
            OpenPanl();
        }

        /// <summary>
        /// //打开选择框区域
        /// </summary>
        private void OpenPanl()
        {
            if (!_isEditState) return;
            if (_isCursorOnPanl)
            {
                _isCursorOnPanl = false;
                //模拟Enter键,取消掉下拉状态
                keybd_event(0xD, 0, 0, 0);
                keybd_event(0xD, 0, 0x0002, 0);

            }
            else
            {

                //创建下拉窗
                ToolStripControlHost toolStripControlHost = new ToolStripControlHost(this.panel);
                toolStripDropDown = new HsToolStripDropDown();
                //设置边框
                toolStripControlHost.Margin = Padding.Empty;
                toolStripControlHost.Padding = Padding.Empty;
                toolStripControlHost.AutoSize = false;
                toolStripDropDown.Padding = Padding.Empty;
                //添加
                toolStripDropDown.Items.Add(toolStripControlHost);             
                toolStripDropDown.Show(this, 0, this.Height);
                //设置宽度最小值
                if (this.panel.Width < this.Width)
                {
                    this.panel.Size = new System.Drawing.Size(this.Width, this.panel.Height);
                }
                //判断关闭时光标在组件内
                toolStripDropDown.Closed = delegate (object sender, ToolStripDropDownClosedEventArgs e1)
                {
                    Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
                    this._isCursorOnPanl = rec.Contains(this.PointToClient(Cursor.Position));
                };
                //设置焦点
                toolStripDropDown.Focus();
            }
        }

        /// <summary>
        /// 绘制下拉面板
        /// </summary>
        private void DrawPanel()
        {
            this.panel = new Panel();
            this.panel.Size = new System.Drawing.Size(this.Width, 100);
            this.panel.Padding = new Padding(1, 1, 1, 13);
            this.panel.BackColor = Color.Gainsboro;
            //绘制边线
            this.panel.Paint = delegate (object sender, PaintEventArgs e)
            {
                ControlPaint.DrawBorder(e.Graphics,
                               this.panel.ClientRectangle,
                               Color.DarkGray,
                               1,
                               ButtonBorderStyle.Solid,
                               Color.DarkGray,
                               1,
                               ButtonBorderStyle.Solid,
                               Color.DarkGray,
                               1,
                               ButtonBorderStyle.Solid,
                               Color.DarkGray,
                               1,
                               ButtonBorderStyle.Solid);
            };
            //使用Label实现右下角拖动按钮
            Label label = new Label();
            label.Text = "◢";
            label.Font = new Font("宋体", 9);
            label.Parent = this.panel;
            label.AutoSize = true;
            label.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right);
            label.Location = new Point(this.panel.Location.X this.panel.Size.Width - label.Width 3,
                this.panel.Location.Y this.panel.Size.Height - label.Height - 1);
            //实现缩放功能
            label.MouseDown = delegate (object sender, MouseEventArgs e1)
            {
                this.pPoint = Cursor.Position;
                this._isMouseDown = true;
            };
            label.MouseLeave = delegate (object sender, EventArgs e1)
            {
                this._isMouseDown = false;
            };
            label.MouseMove = delegate (object sender, MouseEventArgs e1)
            {
                this.cPoint = Cursor.Position;
                if (e1.Button == MouseButtons.Left && _isMouseDown)
                {
                    this.panel.Height = Math.Max(this.panel.Height cPoint.Y - pPoint.Y, 23);
                    this.panel.Width = Math.Max(this.panel.Width cPoint.X - pPoint.X, this.Width);
                    pPoint = Cursor.Position;
                }
                else
                {
                    label.Cursor = Cursors.SizeNWSE;
                }
            };
        }

        
        /// <summary>
        /// 已选定
        /// </summary>
        /// <param name="cname"></param>
        /// <returns></returns>
        private bool IsSelected(string cname)
        {
            bool b = false;
            foreach (Control item in this.flowLayoutPanel2.Controls)
            {
                if (item is UComboxMutiTag)
                {
                    if (cname == ((UComboxMutiTag)item).TagIndex.ToString())
                    {
                        b= true;
                        return b;
                    }
                }
            }
            return b;

        }

        //添加选项
        private void toolStrip2_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

            Deling = false; //标记不删除
            if (IsSelected(e.ClickedItem.Name.ToString())) return;//已选过
            if (!_isEditState) return;           
            UComboxMutiTag tl = new UComboxMutiTag();
            tl.TagText = e.ClickedItem.Text;
            tl.TagIndex = e.ClickedItem.Name;
            tl.BackColor = Color.LightGreen;
            tl.DelClick = Tl_DelClick;
            tl.UEnabled = true;
            this.flowLayoutPanel2.Controls.Add(tl);
        }
        //删除
        private void Tl_DelClick(object sender, EventArgs e)
        {
            Deling = true; //标记删除
            if (toolStripDropDown is null) return; //移动弹窗 
            toolStripDropDown.Hide();

        }
        //框大小编号
        private void flowLayoutPanel2_SizeChanged(object sender, EventArgs e)
        {
            int fheight = flowLayoutPanel2.Size.Height;
            this.Height = fheight 1;
            button1.Height = this.Height;
            if (!_isEditState) return;
            if (toolStripDropDown is null) return; //移动弹窗 
            if (Deling) return; //删除中不显示选框
            toolStripDropDown.Show(this, 0, this.Height);
        }

        private void UComboxMuti_SizeChanged(object sender, EventArgs e)
        {
            panel2.Width = this.Width - 30;
        }


        private void toolStrip2_Paint(object sender, PaintEventArgs e)
        {
            // 去掉ToolStrip底部横线
           CutBottomLine(sender, e);
        }



        private void button1_Click(object sender, EventArgs e)
        {
            OpenPanl();

        }
        #region 去掉ToolStrip底部横线
        /// <summary>
        /// 去掉ToolStrip底部横线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void CutBottomLine(object sender, PaintEventArgs e)
        {
            if (((ToolStrip)sender).RenderMode == ToolStripRenderMode.System)
            {
                Rectangle rect = new Rectangle(0, 0, ((ToolStrip)sender).Width, ((ToolStrip)sender).Height - 2);
                e.Graphics.SetClip(rect);
            }
        }
        #endregion

        #region 停止更新控件
        /// <summary>
        /// The m LST freeze control
        /// </summary>
        static Dictionary<Control, bool> m_lstFreezeControl = new Dictionary<Control, bool>();
        /// <summary>
        /// 功能描述:停止更新控件       
        /// <param name="control">control</param>
        /// <param name="blnToFreeze">是否停止更新</param>
        public static void FreezeControl(Control control, bool blnToFreeze)
        {
            if (blnToFreeze && control.IsHandleCreated && control.Visible && !control.IsDisposed && (!m_lstFreezeControl.ContainsKey(control) || (m_lstFreezeControl.ContainsKey(control) && m_lstFreezeControl[control] == false)))
            {
                m_lstFreezeControl[control] = true;
                control.Disposed = control_Disposed;
                SendMessage(control.Handle, 11, 0, 0);
            }
            else if (!blnToFreeze && !control.IsDisposed && m_lstFreezeControl.ContainsKey(control) && m_lstFreezeControl[control] == true)
            {
                m_lstFreezeControl.Remove(control);
                SendMessage(control.Handle, 11, 1, 0);
                control.Invalidate(true);
            }
        }

        /// <summary>
        /// Sends the message.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="msg">The MSG.</param>
        /// <param name="wParam">The w parameter.</param>
        /// <param name="lParam">The l parameter.</param>
        [DllImport("user32.dll")]
        public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        /// <summary>
        /// Handles the Disposed event of the control control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        static void control_Disposed(object sender, EventArgs e)
        {
            try
            {
                if (m_lstFreezeControl.ContainsKey((Control)sender))
                    m_lstFreezeControl.Remove((Control)sender);
            }
            catch { }
        } 
        #endregion

    }
    //值
    public class ValueItem
    {
        /// <summary>
        /// 书记标题
        /// </summary>
        /// <value>The title.</value>
        public string Title { get; set; }
        /// <summary>
        /// 数据索引ID
        /// </summary>
        /// <value>The details.</value>
        public string IndexID { get; set; }
    }
    /// <summary>
    /// 重写ToolStripDropDown
    /// 使用双缓存减少闪烁
    /// </summary>
    public class HsToolStripDropDown : ToolStripDropDown
    {
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;//双缓存
                return cp;
            }
        }
    }

}