winform--下拉菜单

新建一个用户控件:

 直接上代码:

 /*
     * 作者:pengyan zhang
     * 邮箱:3073507793@qq.com
     * 博客:https://www.cnblogs.com/zpy1993-09
     * 时间:2024-04-12 20:03
     */
    public partial class UCDropControl : UserControl
    {
        #region 事件
        /// <summary>
        /// 委托
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void DropEventHandler(object sender, DataEventArgs e);
        /// <summary>
        /// 开关状态发生改变时引发的事件
        /// </summary>
        public event DropEventHandler DrophEvent;
        #endregion
        #region 属性
        [Category("SimpleUI"), Description("下拉框的边框颜色"), DefaultValue(typeof(Color), "138, 238, 238")]
        public Color UC_BorderColor { get { return borderColor; } set { borderColor = value; Invalidate(); } }
        private Color borderColor { get; set; } = Color.FromArgb(138, 238, 238);
        [Category("SimpleUI"), Description("下拉框边框的大小"), DefaultValue(typeof(int), "5")]
        public int UC_BorderSize { get { return borderSize; } set { borderSize = value; Invalidate(); } }
        private int borderSize { get; set; } = 2;
        [Category("SimpleUI"), Description("下拉框的默认Text")]
        public string UC_Title { get { return Title; } set { Title = value; this.Drop_Title.Text = value; Invalidate(); } }
        private string Title { get; set; } = "请选择";
        [Category("SimpleUI"), Description("当鼠标进入下拉框子项,显示的颜色"), DefaultValue(typeof(Color), "0, 159, 149")]
        public Color UC_EnterDropItemBackColor { get { return EnterDropItemBackColor; } set { EnterDropItemBackColor = value; } }
        private Color EnterDropItemBackColor { get; set; } = Color.FromArgb(0, 159, 149);
        [Category("SimpleUI"), Description("当鼠标离开时,或者默认颜色"), DefaultValue(typeof(Color), "255, 255, 255")]
        public Color UC_LeaveDropItemBackColor { get { return LeaveDropItemBackColor; } set { LeaveDropItemBackColor = value; } }
        private Color LeaveDropItemBackColor { get; set; } = Color.FromArgb(255, 255, 255);
        [Category("SimpleUI"), Description("当鼠标进入的时候,字体颜色"), DefaultValue(typeof(int), "255, 255, 255")]
        public Color UC_EnterDropItemFontColor { get { return EnterDropItemFontColor; } set { EnterDropItemFontColor = value; } }
        private Color EnterDropItemFontColor { get; set; } = Color.FromArgb(255, 255, 255);
        [Category("SimpleUI"), Description("当鼠标离开的时候,或者默认字体颜色"), DefaultValue(typeof(int), "0, 0,0")]
        public Color UC_LeaveDropItemFontColor { get { return LeaveDropitemFontColor; } set { LeaveDropitemFontColor = value; } }
        private Color LeaveDropitemFontColor { get; set; } = Color.FromArgb(0, 0, 0);
        private int UCHeight { get; set; } = 30;
        private FlowLayoutPanel flowLayoutPanel { get; set; }
        private DropOption dropOption { get; set; }
        public string DropName { 
            get {
                if (dropOption == null) return this.Title;
                return dropOption.Title;
            }
        }
        public string DropValue
        {
            get
            {
                if (dropOption == null) return "";
                return dropOption.Id.ToString();
            }
        }

        #endregion
        public UCDropControl()
        {
            InitializeComponent();
            this.Drop_Back.Paint += Drop_Back_Paint;
            Drop_Title.Click += Drop_Click;
            Drop_Pic.Click += Drop_Click;
            Drop_Title.MouseEnter += Drop_MouseEnter_Click;
            Drop_Pic.MouseEnter += Drop_MouseEnter_Click;
            this.Drop_Title.Text = this.Title;
        }
        public void SetDrop(List<DropOption> options)
        {
            //创建FlowLayoutPanel对象
            flowLayoutPanel = new FlowLayoutPanel();
            //放开滚动条
            flowLayoutPanel.AutoScroll = true;
            //禁止横向滚动条
            SetScrollBar(flowLayoutPanel.Handle, 1, 0);//隐藏下、右滚动条
            SetScrollBar(flowLayoutPanel.Handle, 0, 0);
            //计算下拉框子项行高
            int height = 0;
            flowLayoutPanel.Width = this.Width;
            if (options.Count > 0)
            {
                //定义子项
                options.ForEach(item =>
                {
                    //创建子项对象
                    Label label = new Label();
                    label.Tag = item;
                    label.Name = "DropItem";
                    label.AutoSize = false;
                    label.Height = this.Height;
                    label.Width = this.Width;
                    label.BackColor = LeaveDropItemBackColor;
                    label.ForeColor = LeaveDropitemFontColor;
                    if (item.dropType == DropType.文本和图标)
                    {
                        label.ImageAlign = ContentAlignment.MiddleLeft;
                        label.Image = item.image;
                    }
                    label.TextAlign = ContentAlignment.MiddleCenter;
                    if (item.dropType == DropType.字体图标)
                    {
                        label.UseCompatibleTextRendering = true;
                        label.Text = IconfontHelper.GetIconFont(item.StrImage) + "    " + item.Title;
                    }
                    else label.Text = item.Title;
                    label.Click += Drop_Click;
                    label.MouseEnter += Drop_MouseEnter_Click;
                    label.MouseLeave += Drop_MouseLeave_Click;
                    label.Paint += DropItem_Paint;
                    height += this.Height;
                    flowLayoutPanel.Controls.Add(label);
                });
            }
            //如果子项的高大于下拉框的4倍高度,某人为4倍高度
            if (height > this.Height * 4) flowLayoutPanel.Height = this.Height * 4;
            else flowLayoutPanel.Height = height;//如果小于4倍高度,那么就等于累计高度
        }
        private void DropItem_Paint(object? sender, PaintEventArgs e)
        {
            Control control = sender as Control;
            ControlPaint.DrawBorder(e.Graphics,//获取进行绘制的图形
           new Rectangle(0, 0, control.Width, control.Height),//绘制控件所在工作区域
            Color.FromArgb(224, 224, 224), 1, ButtonBorderStyle.Solid,//边框类型,选择实线边框,也有虚线等种类;下面这四个重复的传参是设置工作区上下左右边框的功能
            Color.FromArgb(224, 224, 224), 1, ButtonBorderStyle.Solid,
            Color.FromArgb(224, 224, 224), 1, ButtonBorderStyle.Solid,
            Color.FromArgb(224, 224, 224), 1, ButtonBorderStyle.Solid);
        }
        public void Drop_MouseLeave_Click(object? sender, EventArgs e)
        {
            var control = sender as Control;
            control.BackColor = LeaveDropItemBackColor;
            control.ForeColor = LeaveDropitemFontColor;
        }
        private void Drop_MouseEnter_Click(object? sender, EventArgs e)
        {
            var control = sender as Control;
            control.Cursor = Cursors.Hand;
            if (control.Name == "DropItem")
            {
                control.BackColor = EnterDropItemBackColor;
                control.ForeColor = EnterDropItemFontColor;
            }
        }
        private void Drop_Click(object? sender, EventArgs e)
        {
            if (flowLayoutPanel == null || flowLayoutPanel.Controls.Count == 0) return;
            var control = sender as Control;
            Popup pop;
            switch (control.Name)
            {
                case "Drop_Title":
                case "Drop_Pic":
                    pop = new Popup(flowLayoutPanel);
                    flowLayoutPanel.Tag = pop;
                    pop.Show(this);
                    break;
                case "DropItem":
                    var drop = control.Tag as DropOption;
                     dropOption=drop;
                    this.Drop_Title.Text = drop.Title;
                    pop = flowLayoutPanel.Tag as Popup;
                    if (DrophEvent != null) DrophEvent.Invoke(control, new DataEventArgs(drop));
                    pop.Close();
                    break;
            }
        }
        protected override void OnResize(EventArgs ea)
        {
            this.Height = this.UCHeight;
            base.OnResize(ea);
        }
        private void Drop_Back_Paint(object? sender, PaintEventArgs e)
        {
            ControlPaint.DrawBorder(e.Graphics,//获取进行绘制的图形
            new Rectangle(0, 0, Drop_Back.Width, Drop_Back.Height),//绘制控件所在工作区域
              this.borderColor, this.borderSize, ButtonBorderStyle.Solid,//边框类型,选择实线边框,也有虚线等种类;下面这四个重复的传参是设置工作区上下左右边框的功能
              this.borderColor, this.borderSize, ButtonBorderStyle.Solid,
              this.borderColor, this.borderSize, ButtonBorderStyle.Solid,
              this.borderColor, this.borderSize, ButtonBorderStyle.Solid);
        }
        #region 设置滚动条显示
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int ShowScrollBar(IntPtr hWnd, int bar, int show);

        private class SubWindow : NativeWindow
        {
            private int m_Horz = 0;
            private int m_Show = 0;

            public SubWindow(int p_Horz, int p_Show)
            {
                m_Horz = p_Horz;
                m_Show = p_Show;
            }
            protected override void WndProc(ref Message m_Msg)
            {
                ShowScrollBar(m_Msg.HWnd, m_Horz, m_Show);
                base.WndProc(ref m_Msg);
            }
        }
        /// <summary>
        /// 设置滚动条是否显示
        /// </summary>
        /// <param name="p_ControlHandle">句柄</param>
        /// <param name="p_Horz">0横 1列 3全部</param>
        /// <param name="p_Show">0隐 1显</param>
        public static void SetScrollBar(IntPtr p_ControlHandle, int p_Horz, int p_Show)
        {
            SubWindow _SubWindow = new SubWindow(p_Horz, p_Show);
            _SubWindow.AssignHandle(p_ControlHandle);
        }

        #endregion
    }
    public class DropOption
    {
        public object Id { get; set; }
        public DropType dropType { get; set; } = DropType.文本;
        public Image image { get; set; }
        public string Title { get; set; }
        public string StrImage { get; set; }
    }
   public enum DropType
    {
        文本,
        文本和图标,
        字体图标
    }
 private void InitData()
        {
            var optlist = new List<DropOption>()
            {
                new DropOption(){Id="1",dropType=DropType.文本,Title="标题1"},
                 new DropOption(){Id="2",dropType=DropType.文本,Title="标题2"},
                new DropOption(){Id="3",dropType=DropType.文本,Title="标题3"},
                new DropOption(){Id="4",dropType=DropType.文本,Title="标题4"},


            };
            ucDropControl1.SetDrop(optlist);

        }

 

效果:

 

posted @ 2024-07-22 15:04  代码如风~~~  阅读(82)  评论(0编辑  收藏  举报