实现OutlookBar
实现:
利用OutlookBar命名空间
OutlookBar.cs:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace OutlookBar
{
internal class BandTagInfo
{
public OutlookBar outlookBar;
public int index;
public BandTagInfo(OutlookBar ob, int index)
{
outlookBar = ob;
this.index = index;
}
}
public class OutlookBar : Panel
{
private int buttonHeight;
private int selectedBand;
private int selectedBandHeight;
public int ButtonHeight
{
get
{
return buttonHeight;
}
set
{
buttonHeight = value;
// do recalc layout for entire bar
}
}
public int SelectedBand
{
get
{
return selectedBand;
}
set
{
SelectBand(value);
}
}
public OutlookBar()
{
buttonHeight = 25;
selectedBand = 0;
selectedBandHeight = 0;
}
public void Initialize()
{
// parent must exist!
Parent.SizeChanged += new EventHandler(SizeChangedEvent);
}
public void AddBand(string caption, ContentPanel content)
{
content.outlookBar = 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;
// the band dimensions
bandPanel.Location = new Point(0, vPos);
bandPanel.Size = new Size(ClientRectangle.Width, height);
// the contained button dimensions
bandPanel.Controls[0].Location = new Point(0, 0);
bandPanel.Controls[0].Size = new Size(ClientRectangle.Width, buttonHeight);
// the contained content panel dimensions
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 OutlookBar outlookBar;
public ContentPanel()
{
// initial state
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; // icon height + text height + margin
BackColor = Color.LightBlue;
AutoScroll = true;
}
public void AddIcon(string caption, Image image, EventHandler onClickEvent)
{
int index = Controls.Count / 2; // two entries per icon
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;
}
}
}
}
程序中调用:
OutlookBar outlookBar=new OutlookBar();
int i=0;//记录面板总索引
IconPanel currentpanel;//记录当前的面板;
InitializeComponent();
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//创建outlookbar
outlookBar.Location=new Point(0, 0);
outlookBar.Size=new Size(120, this.ClientSize.Height);
outlookBar.BorderStyle=BorderStyle.FixedSingle;
Controls.Add(outlookBar);
outlookBar.Initialize();
//创建类别面板
IconPanel iconPanel1=new IconPanel();
IconPanel iconPanel2=new IconPanel();
IconPanel iconPanel3=new IconPanel();
outlookBar.AddBand("Outlook Shortcuts", iconPanel1);
outlookBar.AddBand("My Shortcuts", iconPanel2);
outlookBar.AddBand("Other Shortcuts", iconPanel3);
//创建类面板下的子项目
iconPanel1.AddIcon("Outlook Today", Image.FromFile("img1.ico"), new EventHandler(PanelEvent));
iconPanel1.AddIcon("Calendar", Image.FromFile("img2.ico"), new EventHandler(PanelEvent));
iconPanel1.AddIcon("Contacts", Image.FromFile("img3.ico"), new EventHandler(PanelEvent));
iconPanel1.AddIcon("Tasks", Image.FromFile("img4.ico"), new EventHandler(PanelEvent));
//选择面板
outlookBar.SelectBand(0);
//相应子项目的事件
public void PanelEvent(object sender, EventArgs e)
{
Control ctrl=(Control)sender;
PanelIcon panelIcon=ctrl.Tag as PanelIcon;
MessageBox.Show("#"+panelIcon.Index.ToString(), "Panel Event");
}
private void button1_Click(object sender, System.EventArgs e)
{
string panelname="新增组";
WindowsApplication1.Form2 f2 =new WindowsApplication1.Form2();
DialogResult d=f2.ShowDialog(this);
if(d==DialogResult.OK)
{
panelname=f2.textBox1.Text;
}
//新增组面板
IconPanel panel=new IconPanel();
outlookBar.AddBand(panelname, panel);
currentpanel=panel;
outlookBar.SelectBand(3);
}
private void button2_Click(object sender, System.EventArgs e)
{
//在当前组新增项目
currentpanel.AddIcon("新增项目",Image.FromFile("img1.ico"),new EventHandler(PanelEvent));
}
private void button3_Click(object sender, System.EventArgs e)
{
//得到被选的面板索引
int index=outlookBar.SelectedBand;
outlookBar.SelectBand(index);
}