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

        public int ButtonHeight { get; set; }

        public int SelectedBand { get; set; }

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

        /// <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()
        {
            ; 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 = , vPos);
            mainPanel.Size = new Size(ClientRectangle.Width, height);

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

            //计算内容尺寸
            mainPanel.Controls[].Location = , ButtonHeight);
            mainPanel.Controls[].Size = , height - );
        }

        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);

            ; i <= ; i++)
            {
                panel1.Controls.Add(new Button() { Text = i.ToString() });
            }
            ; i <= ; i++)
            {
                panel2.Controls.Add(new Button() { Text = i.ToString() });
            }
            ; i <= ; i++)
            {
                panel3.Controls.Add(new Button() { Text = i.ToString() });
            }
            outlookBar.SelectBand();
        }

调用方式

效果图:

windows from 手风琴的更多相关文章

  1. Windows server 2012 添加中文语言包(英文转为中文)(离线)

    Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...

  2. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  3. C# 注册 Windows 热键

    闲扯: 前几日,一个朋友问我如何实现按 F1 键实现粘贴(Ctrl+V)功能,百度了一个方法,发给他,他看不懂(已经是 Boss 的曾经的码农),我就做了个Demo给他参考.今日得空,将 Demo 整 ...

  4. Windows 7上执行Cake 报错原因是Powershell 版本问题

    在Windows 7 SP1 电脑上执行Cake的的例子 http://cakebuild.net/docs/tutorials/getting-started ,运行./Build.ps1 报下面的 ...

  5. 在离线环境中发布.NET Core至Windows Server 2008

    在离线环境中发布.NET Core至Windows Server 2008 0x00 写在开始 之前一篇博客中写了在离线环境中使用.NET Core,之后一边学习一边写了一些页面作为测试,现在打算发布 ...

  6. Windows平台分布式架构实践 - 负载均衡

    概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行.那么大家(开发者和企业)为 ...

  7. dll文件32位64位检测工具以及Windows文件夹SysWow64的坑

    自从操作系统升级到64位以后,就要不断的需要面对32位.64位的问题.相信有很多人并不是很清楚32位程序与64位程序的区别,以及Program Files (x86),Program Files的区别 ...

  8. 在docker中运行ASP.NET Core Web API应用程序(附AWS Windows Server 2016 widt Container实战案例)

    环境准备 1.亚马逊EC2 Windows Server 2016 with Container 2.Visual Studio 2015 Enterprise(Profresianal要装Updat ...

  9. 1.初始Windows Server 2012 R2 Hyper-V + 系统安装详细

    干啥的?现在企业服务器都是分开的,比如图片服务器,数据库服务器,redis服务器等等,或多或少一个网站都会用到多个服务器,而服务器的成本很高,要是动不动采购几十台,公司绝对吃不消的,于是虚拟化技术出来 ...

随机推荐

  1. Spark技术内幕:Worker源码与架构解析

    首先通过一张Spark的架构图来了解Worker在Spark中的作用和地位: Worker所起的作用有以下几个: 1. 接受Master的指令,启动或者杀掉Executor 2. 接受Master的指 ...

  2. J2EE进阶(三)struts2 <s:action>标签的用法

    J2EE进阶(三)struts2 <s:action>标签的用法 前言 使用action标签,可以允许在jsp页面中直接调用Action,(类似AJAX页面调用)在调用Action时候,可 ...

  3. Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(七)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 打开SpriteBuilder,在文件视图中新建一个文件夹Fon ...

  4. RabbitMQ消息队列(五):Routing 消息路由

        上篇文章中,我们构建了一个简单的日志系统.接下来,我们将丰富它:能够使用不同的severity来监听不同等级的log.比如我们希望只有error的log才保存到磁盘上. 1. Bindings ...

  5. 从JDK源码角度看java并发线程的中断

    线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...

  6. springMVC参数的传递方式(1.通过@PathVariabl获取路径参数,2.@ModelAttribute获取数据,3.HttpServletRequest取参,4@RequestParam)

     通过@PathVariabl注解获取路径中传递参数 JAVA      @RequestMapping(value = "/{id}/{str}")      public  ...

  7. 什么是IOC

    什么是IOC         IOC:控制反转,控制权的转移,应用程序本身不负责对象的创建和维护,而是由外部容器负责创建和维护.        DI(依赖注入)是其一种实现方式        目的:创 ...

  8. Oracle PL/SQL Articles

    我是搬运工....http://www.oracle-base.com/articles/plsql/articles-plsql.php Oracle 8i Oracle 9i Oracle 10g ...

  9. JSP编译成Servlet(二)语法树的遍历——访问者模式

    语法树可以理解成是一种数据结构,假如某些语句已经被解析成一棵语法树,那么接下来就是要对此语法树进行处理,但考虑到不将处理操作与数据结构混合在一块,我们需要一种方法将其分离.其实对于语法树的处理最典型的 ...

  10. ssh连接原理介绍( 无密码连接登录的原理)

    SSH(Secure  Shell)一种在不安全网络上提供安全远程登录及其它安全网络服务的协议.由客户端和服务端的软件组成的,有两个不兼容的版本分别是:1.x和2.x.(SSH 2.x的客户程序是不能 ...