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. 【OpenGL】详解第一个OpenGL程序

    写在前面 OpenGL能做的事情太多了!很多程序也看起来很复杂.很多人感觉OpenGL晦涩难懂,原因大多是被OpenGL里面各种语句搞得头大,一会gen一下,一会bind一下,一会又active一下. ...

  2. 微信小程序的开发:通过微信小程序看前端

    前言 2016年9月22日凌晨,微信官方通过"微信公开课"公众号发布了关于微信小程序(微信应用号)的内测通知.整个朋友圈瞬间便像炸开了锅似的,各种揣测.介绍性文章在一夜里诞生.而真 ...

  3. System.getProperty()的用途

     偶尔用到 System.getProperty(),找起来也不方便.这里做下记录备忘: 编写的测试类: public class TestSystemproperty { public stat ...

  4. python 远程调度进程服务与客户端

    python 远程调度进程服务与客户端 核心思想: 在本地或远程机器上创建一个进程,提供调度服务.使用了 APScheduler. 安装:APScheduler $ wget https://pypi ...

  5. Qt中事件分发源代码剖析

    Qt中事件分发源代码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,并且进行分发,这些都是在exec中进行的. 下面举例说明: 1)首先看看下面一段示例代码: i ...

  6. Nginx Upstream模块源码分析(上)

    Upstream模块是一个很重要的模块,很多其他模块都会使用它来完成对后端服务器的访问, 达到反向代理和负载均衡的效果.例如Fastcgi.Memcached.SessionSticky等. 如果自己 ...

  7. UNIX网络编程——心跳包

    所谓的心跳包就是在客户端和服务器端间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包. 一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定 ...

  8. iOS中 Swift初级入门学习(三)

    // // main.swift // LessonSwift-03 // // Copyright (c) 2015年 韩俊强. All rights reserved. // import Fou ...

  9. iOS中类单例方法的一种实现

    在Cocos2D编程中,很多情况我们需要类只生成一个实例,这称之为该类的单例类. 一般我们在类中这样实现单例方法: +(instancetype)sharedInstance{ static Foo ...

  10. 从JDK源码角度看线程的阻塞和唤醒

    目前在Java语言层面能实现阻塞唤醒的方式一共有三种:suspend与resume组合.wait与notify组合.park与unpark组合.其中suspend与resume因为存在无法解决的竟态问 ...