• 【C#】自定义容器控件,设置界面控件,支持设计器拖入控件


    先上效果图:

    1、先重写设置界面的控件功能:

        public partial class SetterControl : UserControl
        {
            public SetterControl()
            {
                InitializeComponent();
                Initialize();
            }
            /// <summary>
            /// 获取或设置组列表
            /// </summary>
            public Dictionary<string, List<SetterStrip>> Items;
            /// <summary>
            /// 容器
            /// </summary>
            public Panel ItemContainer
            { get; set; }
            ///// <summary>
            ///// 加载
            ///// </summary>
            ///// <param name="e"></param>
            //protected override void OnLoad(EventArgs e)
            //{
            //    base.OnLoad(e);
            //}
            /// <summary>
            /// 鼠标按下
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseDown(MouseEventArgs e)
            {
                base.OnMouseDown(e);
                this.Invalidate();
            }
            /// <summary>
            /// 鼠标移动
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseMove(MouseEventArgs e)
            {
                base.OnMouseMove(e);
                this.Invalidate();
            }
            /// <summary>
            /// 鼠标弹起
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseUp(MouseEventArgs e)
            {
                base.OnMouseUp(e);
                if (Items == null) return;
                int index = 0;
                Point p = new Point(e.X, e.Y);
                foreach (var v in Items)
                {
                    Rectangle rect = new Rectangle(_itemW * index, 0, _itemW, _itemH);
                    if (rect.Contains(p))
                    {
                        _titleIndex = index;
                        _itemIndex = 0;
                        break;
                    }
                    if (_titleIndex == index)
                    {
                        int i = 0;
                        foreach (var item in v.Value)
                        {
                            rect = new Rectangle(0, i * (_itemH - 10) + _itemH, _itemW, (_itemH - 10));
                            if (rect.Contains(p))
                            {
                                _itemIndex = i;
                                if (ItemContainer != null && item.LocationControl != null)
                                    ItemContainer.ScrollControlIntoView(item.LocationControl);
                                break;
                            }
                            i++;
                        }
                    }
                    index++;
                }
                this.Invalidate();
            }
            /// <summary>
            /// 绘制
            /// </summary>
            /// <param name="e"></param>
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                Brush brush = new SolidBrush(Color.FromArgb(238, 238, 238));
                e.Graphics.FillRectangle(brush, new Rectangle(0, 0, this.Width, _itemH));
                e.Graphics.FillRectangle(brush, new Rectangle(0, 0, _itemW, this.Height));
                if (Items != null)
                {
                    Point p = this.PointToClient(Control.MousePosition);
                    StringFormat sf = new StringFormat()
                    {
                        LineAlignment = StringAlignment.Center
                    };
                    int index = 0;
                    foreach (var v in Items)
                    {
                        Rectangle rect = new Rectangle(_itemW * index, 0, _itemW, _itemH);
                        Brush b = index == _titleIndex ? Brushes.BlueViolet : rect.Contains(p) ? Brushes.Gold : Brushes.Black;
                        if (index == 0) rect.Offset(20, 0);
                        e.Graphics.DrawString(v.Key, this.Font, b, rect, sf);
                        if (index == _titleIndex)
                        {
                            int i = 0;
                            foreach (var item in v.Value)
                            {
                                rect = new Rectangle(0, i * (_itemH - 10) + _itemH, _itemW, (_itemH - 10));
                                b = i == _itemIndex ? Brushes.White : rect.Contains(p) ? Brushes.LightGray : brush;
                                e.Graphics.FillRectangle(b, rect);
                                rect.Offset(20, 0);
                                e.Graphics.DrawString(item.Name, this.Font, Brushes.Black, rect, sf);
                                i++;
                            }
                        }
                        index++;
                    }
                }
                e.Graphics.DrawLine(Pens.Gray, new Point(0, _itemH), new Point(this.Width, _itemH));
                brush.Dispose();
            }
    
            /// <summary>
            /// 初始化
            /// </summary>
            private void Initialize()
            {
                this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
            }
            
            private const int _itemH = 50;
            private const int _itemW = 130;
            private int _titleIndex;
            private int _itemIndex;
        }
        [Serializable]
        public class SetterStrip
        {
            /// <summary>
            /// 组名
            /// </summary>
            public string Name
            { get; set; }
            /// <summary>
            /// 组控件坐标
            /// </summary>
            public Control LocationControl
            { get; set; }
        }

    2、实现设计器上直接拖入控件功能

        [Designer(typeof(LDesigner))]
        [DesignTimeVisible(true)]
        public class MenuControlEx : SetterControl
        {
            public MenuControlEx()
            {
                InitializeComponent();
            }
            /// <summary>
            /// 获取存放控件的Panel
            /// </summary> 
            [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            public Panel MenuPanel
            { get { return setterPanel; } }
    
            private void InitializeComponent()
            {
                this.setterPanel = new System.Windows.Forms.Panel();
                this.SuspendLayout();
                // 
                // setterPanel
                // 
                this.setterPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right)));
                this.setterPanel.AutoScroll = true;
                this.setterPanel.Location = new System.Drawing.Point(131, 52);
                this.setterPanel.Name = "setterPanel";
                this.setterPanel.Size = new System.Drawing.Size(475, 499);
                this.setterPanel.TabIndex = 0;
                // 
                // MenuControlEx
                // 
                this.Controls.Add(this.setterPanel);
                this.ItemContainer = this.setterPanel;
                this.Name = "MenuControlEx";
                this.ResumeLayout(false);
    
            }
            private System.Windows.Forms.Panel setterPanel;
        }
    
    
        public class LDesigner : ParentControlDesigner
        {
            private MenuControlEx _control;
    
            public override void Initialize(IComponent component)
            {
                base.Initialize(component);
                _control = (MenuControlEx)component;
                bool succ = this.EnableDesignMode(_control.MenuPanel, "setterPanel");
                if (!succ)
                    throw new Exception("加载控件失败");
            }
        }

    3、使用方法:

    Dictionary<string, List<DLL.Controls.SetterStrip>> items = new Dictionary<string, List<DLL.Controls.SetterStrip>>();
                items.Add("基础设置", new List<DLL.Controls.SetterStrip>() { 
    new DLL.Controls.SetterStrip() {Name="常规", LocationControl=button1 },
     new DLL.Controls.SetterStrip() { Name = "快捷键", LocationControl = button2 },
     new DLL.Controls.SetterStrip() { Name = "显示", LocationControl = button3 } 
    });
                items.Add("安全设置", new List<DLL.Controls.SetterStrip>() { 
    new DLL.Controls.SetterStrip() { Name = "安全1", LocationControl = button1 },
     new DLL.Controls.SetterStrip() { Name = "安全2", LocationControl = button2 }, 
    new DLL.Controls.SetterStrip() { Name = "安全3", LocationControl = button3 } 
    });
    menuControlEx1.Items = items;
    //Name是显示的,LocationControl是用来点击按钮,控制滚动条定位的

    2018/7/15 补上测试工程

    源码下载 

    PS. 如果是DLL方式使用,引用该DLL的地方也要引用 System.Design,否则会报错

    如果需要技术交流的,可以关注微信公众号:梦琪动漫屋 

  • 相关阅读:
    centos7.5部署mysql cluster NDB总结
    读《构建之法》13--17章有感
    读《构建之法》8--10章
    作业5.2
    作业5.1
    读《构建之法》6--7章读后感
    做汉堡,做汉堡
    《构建之法》1—5章读后感
    第二次作业
    1
  • 原文地址:https://www.cnblogs.com/mqxs/p/8691817.html
Copyright © 2020-2023  润新知