public class OutlookBar : Panel
    {
        private int SelectedBandHeight { get; set; }

        public int ButtonHeight { get; set; }

        public int SelectedBand { get; set; }

        public OutlookBar()
        {
            ButtonHeight = 25;
            SelectedBand = 0;
            SelectedBandHeight = 0;
        }

        /// <summary>
        /// 初始化位置
        /// </summary>
        public void Initialize()
        {
            Parent.SizeChanged += new EventHandler(SizeChangedEvent);
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="text"></param>
        /// <param name="panel"></param>
        public void AddBand(string text, Panel panel)
        {
            var index = Controls.Count;
            MainPanel bandPanel = new MainPanel(new Model() { OutlookBar = this, Index = index, Text = text, Panel = panel });

            Controls.Add(bandPanel);
            UpdateBarInfo();
            RecalcLayout(bandPanel, index);
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <param name="index"></param>
        public void SelectBand(int index)
        {
            SelectedBand = index;
            RedrawBands();
        }

        private void RedrawBands()
        {
            for (int i = 0; i < Controls.Count; i++)
            {
                MainPanel bp = Controls[i] as MainPanel;
                RecalcLayout(bp, i);
            }
        }

        /// <summary>
        /// 更新
        /// </summary>
        private void UpdateBarInfo()
        {
            SelectedBandHeight = ClientRectangle.Height - (Controls.Count * ButtonHeight);
        }

        /// <summary>
        /// 重新计算布局
        /// </summary>
        /// <param name="mainPanel"></param>
        /// <param name="index"></param>
        private void RecalcLayout(MainPanel mainPanel, int index)
        {
            int vPos = (index <= SelectedBand) ? ButtonHeight * index : ButtonHeight * index + SelectedBandHeight;
            int height = SelectedBand == index ? SelectedBandHeight + ButtonHeight : ButtonHeight;

            //主面板尺寸
            mainPanel.Location = new Point(0, vPos);
            mainPanel.Size = new Size(ClientRectangle.Width, height);

            //计算按钮尺寸
            mainPanel.Controls[0].Location = new Point(0, 0);
            mainPanel.Controls[0].Size = new Size(ClientRectangle.Width, ButtonHeight);

            //计算内容尺寸
            mainPanel.Controls[1].Location = new Point(0, ButtonHeight);
            mainPanel.Controls[1].Size = new Size(ClientRectangle.Width - 2, height - 8);
        }

        private void SizeChangedEvent(object sender, EventArgs e)
        {
            Size = new Size(Size.Width, ((Control)sender).ClientRectangle.Size.Height);
            UpdateBarInfo();
            RedrawBands();
        }
    }

手风琴 主体代码

class MainPanel : Panel
    {
        public Model model { get; set; }

        public MainPanel(Model obj)
        {
            this.model = obj;

            Button btn = new Button() { Text = obj.Text, FlatStyle = FlatStyle.Standard, Visible = true };
            btn.Click += new EventHandler(SelectBand);


            this.model.Panel.AutoScroll = true;
            this.model.Panel.Dock = DockStyle.Fill;

            Controls.Add(btn);
            Controls.Add(this.model.Panel);
        }
        private void SelectBand(object sender, EventArgs e)
        {
            model.OutlookBar.SelectBand(model.Index);
        }
    }

主体Panel

  class Model
    {
        public OutlookBar OutlookBar { get; set; }

        public int Index { get; set; }

        public string Text { get; set; }

        public Panel Panel { get; set; }
    }

实体类

 private void DataBindBar()
        {
            outlookBar.Initialize();
            var panel1 = new TableLayoutPanel();
            var panel2 = new TableLayoutPanel();
            var panel3 = new TableLayoutPanel();

            outlookBar.AddBand("工具条A", panel1);
            outlookBar.AddBand("工具条B", panel2);
            outlookBar.AddBand("工具条C", panel3);

            for (int i = 0; i <= 200; i++)
            {
                panel1.Controls.Add(new Button() { Text = i.ToString() });
            }
            for (int i = 0; i <= 25; i++)
            {
                panel2.Controls.Add(new Button() { Text = i.ToString() });
            }
            for (int i = 0; i <= 30; i++)
            {
                panel3.Controls.Add(new Button() { Text = i.ToString() });
            }
            outlookBar.SelectBand(0);
        }

调用方式

效果图:

版权声明:本文为shuyu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/shuyu/p/8984020.html