QQ效果

来源:互联网 发布:啪啪影院软件下载 编辑:程序博客网 时间:2024/04/29 09:00

基本思路
Panel的组合+Panel内部的图标组合

布局
可以看作是三个Panel,每个Panel都有其Title部分和Content部分.Title部分是唯一的,由一个Button来表达,Button的样式设置为最普通的,而且锚定Dock是Top的,这样它就可以居顶了.
Content部分位于每个Band的下半部分,是一个有背景颜色的Panel,而在这个Panel中有序地放置了不同的图标和文字,图标+文字可以是一个小的控件,如一个小的Panel,由PictureBox+Label来实现,它们在Content中的显示有按普通顺序了.也就是先入先显示或先入后显示.

动作
OutlookBar有一个selectBand的属性,当点击其它Band的时候,就会设置selectBand为其它的,选定的Band,将展示Content域.这相当于一个重新计算的过程,也就是说原有的selectBand的Content域在收缩起来,新的展开来.控件变大变小自适应,OutlookBar应该可以随着Form的大小变化而变化,这也是相当容易的,可以设置整个OutlookBar的Dock属性.这样以达到锚定的功能.

实体设计
QBar类,里面有selectBand属性,而各个Band都可以由OutlookBar来获取.有一个Band的类,这个类包括Title实体和Content实体的定义,当前,也可以将这三个实体分开.另外,为了实现Content里面的内容可定制,如可以放TreeView,DataGridView等,增加AddControl方法,增加自已想要的控件

using System;
using System.Drawing;
using System.Windows.Forms;

namespace QBar
{
  class BandTagInfo
 {
  public QBar qBar;
  public int index;

  public BandTagInfo(QBar ob, int index)
  {
   qBar=ob;
   this.index=index;
  }
 }

 public class QBar : Panel
 {
  private int buttonHeight;
  private int selectedBand;
  private int selectedBandHeight;

  public int ButtonHeight
  {
   get
   {
    return buttonHeight;
   }

   set
   {
    buttonHeight=value;
   }
  }

  public int SelectedBand
  {
   get
   {
    return selectedBand;
   }
   set
   {
    SelectBand(value);
   }
  }

  public QBar()
  {
   buttonHeight=25;
   selectedBand=0;
   selectedBandHeight=0;
  }

  public void Initialize()
  {
   Parent.SizeChanged+=new EventHandler(SizeChangedEvent);
  }

  public void AddBand(string caption, ContentPanel content)
  {
   content.qBar=this;
   int index=Controls.Count;
   BandTagInfo bti=new BandTagInfo(this, index);
   BandPanel bandPanel=new BandPanel(caption, content, bti);
   Controls.Add(bandPanel);
   UpdateBarInfo();
   RecalcLayout(bandPanel, index);
  }

  public void SelectBand(int index)
  {
   selectedBand=index;
   RedrawBands();
  }

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

  private void UpdateBarInfo()
  {
   selectedBandHeight=ClientRectangle.Height-(Controls.Count * buttonHeight);
  }

  private void RecalcLayout(BandPanel bandPanel, int index)
  {
   int vPos=(index <= selectedBand) ? buttonHeight*index : buttonHeight*index+selectedBandHeight;
   int height=selectedBand==index ? selectedBandHeight+buttonHeight : buttonHeight;


   bandPanel.Location=new Point(0, vPos);
   bandPanel.Size=new Size(ClientRectangle.Width, height);


   bandPanel.Controls[0].Location=new Point(0, 0);
   bandPanel.Controls[0].Size=new Size(ClientRectangle.Width, buttonHeight);


   bandPanel.Controls[1].Location=new Point(0, buttonHeight);
   bandPanel.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();
  }
 }

 internal class BandPanel : Panel
 {
  public BandPanel(string caption, ContentPanel content, BandTagInfo bti)
  {
   BandButton bandButton=new BandButton(caption, bti);
   Controls.Add(bandButton);
   Controls.Add(content);
  }
 }

 internal class BandButton : Button
 {
  private BandTagInfo bti;

  public BandButton(string caption, BandTagInfo bti)
  {
   Text=caption;
   FlatStyle=FlatStyle.Standard;
   Visible=true;
   this.bti=bti;
   Click+=new EventHandler(SelectBand);
  }

  private void SelectBand(object sender, EventArgs e)
  {
   bti.outlookBar.SelectBand(bti.index);
  }
 }

 public abstract class ContentPanel : Panel
 {
  public QBar qBar;

  public ContentPanel()
  {
   Visible=true;
  }
 }

 public class IconPanel : ContentPanel
 {
  protected int iconSpacing;
  protected int margin;

  public int IconSpacing
  {
   get
   {
    return iconSpacing;
   }
  }

  public int Margin
  {
   get
   {
    return margin;
   }
  }

  public IconPanel()
  {
   margin=10;
   iconSpacing=32+15+10; 
   BackColor=Color.LightBlue;
   AutoScroll=true;
  }

  public void AddIcon(string caption, Image image, EventHandler onClickEvent)
  {
   int index=Controls.Count/2; 
   PanelIcon panelIcon=new PanelIcon(this, image, index, onClickEvent);
   Controls.Add(panelIcon);

   Label label=new Label();
   label.Text=caption;
   label.Visible=true;
   label.Location=new Point(0, margin+image.Size.Height+index*iconSpacing);
   label.Size=new Size(Size.Width, 15);
   label.TextAlign=ContentAlignment.TopCenter;
   label.Click+=onClickEvent;
   label.Tag=panelIcon;
   Controls.Add(label);
  }
 }

 public class PanelIcon : PictureBox
 {
  public int index;
  public IconPanel iconPanel;

  private Color bckgColor;
  private bool mouseEnter;

  public int Index
  {
   get
   {
    return index;
   }
  }

  public PanelIcon(IconPanel parent, Image image, int index, EventHandler onClickEvent)
  {
   this.index=index;
   this.iconPanel=parent;
   Image=image;
   Visible=true;
   Location=new Point(iconPanel.outlookBar.Size.Width/2-image.Size.Width/2,
       iconPanel.Margin + index*iconPanel.IconSpacing);
   Size=image.Size;
   Click+=onClickEvent;
   Tag=this;

   MouseEnter+=new EventHandler(OnMouseEnter);
   MouseLeave+=new EventHandler(OnMouseLeave);
   MouseMove+=new MouseEventHandler(OnMouseMove);

   bckgColor=iconPanel.BackColor;
   mouseEnter=false;
  }

  private void OnMouseMove(object sender, MouseEventArgs args)
  {
   if ( (args.X < Size.Width-2) &&
    (args.Y < Size.Width-2) &&
    (!mouseEnter) )
   {
    BackColor=Color.LightCyan;
    BorderStyle=BorderStyle.FixedSingle;
    Location=Location-new Size(1, 1);
    mouseEnter=true;
   }
  }

  private void OnMouseEnter(object sender, EventArgs e)
  {
  }

  private void OnMouseLeave(object sender, EventArgs e)
  {
   if (mouseEnter)
   {
    BackColor=bckgColor;
    BorderStyle=BorderStyle.None;
    Location=Location+new Size(1, 1);
    mouseEnter=false;
   }
  }
 }
}

原创粉丝点击