先上張效果圖,依次為全展開圖,部分折疊圖,全部折疊圖
代碼下載:http://www.BkJia.com/uploadfile/2012/0509/20120509024345964.rar
時間倉促,功能相對簡單,也未經過詳細測試,不支持設計期操作,這裡提供思路給大家,有時間完善吧,上代碼:
代碼文件介紹
NavBar.cs 導航欄主體,繼承自 Panel
NavGroup.cs NavBar中的分組,即(控制面板,我的電腦等),繼承自Control
NavBarItem.cs 分組中的小項(即區域選項,字體等),繼承自Control
NavBarButton.cs 導航欄主體右邊的圓形按鈕
NavGroupCollection.cs 分組的集合
NavBarItemCollection.cs 分組中小項的集合
NavGroupState.cs 組的狀態,收縮還是展開
NavBar.cs
[csharp]
using System;
using System.Collections.Generic;
using System.Drawing.Design;
using System.ComponentModel.Design;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class NavBar : Panel
{
private NavGroupCollection _groups;
public NavGroupCollection Groups
{
get { return this._groups; }
}
public NavGroup this[int index]
{
get
{
if (index > -1)
return this._groups[index];
else
return null;
}
}
private int _selectedIndex = -1;
/// <summary>
/// 選擇組的索引
/// </summary>
[DefaultValue(-1)]
public int SelectedIndex
{
get { return this._selectedIndex; }
set
{
this._selectedIndex = value;
this.SelectGroup(value);
}
}
private int _groupSpace = 20;
/// <summary>
/// Group間距
/// </summary>
public int GroupSpace
{
get { return this._groupSpace; }
set { this._groupSpace = value; }
}
private int _groupMargin = 5;
/// <summary>
/// Group邊距
/// </summary>
public int GroupMargin
{
get { return this._groupMargin; }
set { this._groupMargin = value; }
}
private ImageList _smallImageList;
/// <summary>
/// 設置圖像列表
/// </summary>
public ImageList SmallImageList
{
get { return this._smallImageList; }
set { this._smallImageList = value; }
}
public NavBar()
{
InitializeComponent();
this.BackColor = Color.FromArgb(112, 140, 225);
this._groups = new NavGroupCollection(this);
this.AutoScroll = true;
}
/// <summary>
/// 根據添加的項,布局
/// </summary>
/// <param name="item"></param>
public void SetLayOut(NavGroup item)
{
this.SuspendLayout();
this.Controls.Add(item);
if (this._groups.Count == 0)
{
item.Top = 10;
}
else
{
item.Top = this[this._groups.Count - 1].Bottom + this.GroupSpace;
}
item.Width = this.Width - 2 * this.GroupMargin;
item.Left = (this.Width - item.Width) / 2;
item.Height = item.TitleHeight;
this.ResumeLayout();
//item.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
}
/// <summary>
/// 重新布局組件
/// </summary>
public void SetLayOut()
{
for (int i = 0; i < this._groups.Count; i++)
{
if (i == 0)
this._groups[i].Top = 10;
else
{
this._groups[i].Top = this._groups[i - 1].Bottom + this._groupSpace;
this._groups[i].GroupIndex = i;
}
}
}
/// <summary>
/// 添加分組
/// </summary>
/// <returns></returns>
public NavGroup AddGroup()
{
this._groups.Add();
return this._groups[this._groups.Count - 1];
}
/// <summary>
/// 刪除分組
/// </summary>
/// <param name="item"></param>
public void RemoveGroup(NavGroup item)
{
int i = item.GroupIndex;
this._groups.Remove(item);
this.Controls.Remove(item);
this.SetLayOut();
}
/// <summary>
/// 刪除指定索引的分組
/// </summary>
/// <param name="index"></param>
public void RemoveGroupAt(int index)
{
this.Controls.Remove(this._groups[index]);
this._groups.RemoveAt(index);
this.SetLayOut();
}
/// <summary>
/// 選中指定索引的分組
/// </summary>
/// <param name="index"></param>
private void SelectGroup(int index)
{
foreach (NavGroup g in this._groups)
{
if (g.GroupIndex == this._selectedIndex) continue;
g.IsSelected = false;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
}
}
}
NavGroup.cs
[csharp]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class NavGroup : Control
{
private Rectangle _titleRectangle;
private NavBar _ownerBar;
private NavBarButton _button;
private NavBarItemCollection _items;
public NavBarItemCollection Items
{
get { return this._items; }
set { this._items = value; }
}
public NavBarItem this[int index]
{
get
{
if (index > -1)
return this._items[index];
else
return null;
}
}
private NavGroupState _groupState = NavGroupState.expand;
/// <summary>
/// 組的狀態
/// </summary>
public NavGroupState GroupState
{
get { return this._groupState; }
set
{
this._groupState = value;
this.SetGroupState(value);
}
}
private int _groupIndex;
/// <summary>
/// 組索引
/// </summary>
public int GroupIndex
{
get { return this._groupIndex; }
set { this._groupIndex = value; }
}
private int _titleHeight = 20;
/// <summary>
/// 標題高度
/// </summary>
public int TitleHeight
{
get { return this._titleHeight; }
set
{
this._titleHeight = value;
this.SetTitleRectangle();
}
}
private string _title;
/// <summary>
/// 標題
/// </summary>
public string Title
{
get { return this._title; }
set { this._title = value; }
}
private Color _titleStartColor = Color.White;
/// <summary>
/// 標題漸變開始色
/// </summary>
public Color TitleStartColor
{
get { return this._titleStartColor; }
set
{
this._titleStartColor = value;
}
}
private Color _titleEndColor = Color.FromArgb(199, 211, 247);
/// <summary>
/// 標題漸變結束色
/// </summary>
public Color TitleEndColor
{
get { return this._titleEndColor; }
set
{
this._titleEndColor = value;
}
}
private int _itemSpace = 5;
/// <summary>
/// Item間距
/// </summary>
public int ItempSpace
{
get { return this._itemSpace; }
set { this._itemSpace = value; }
}
private int _itemMargin = 5;
/// <summary>
/// Item邊距
/// </summary>
public int ItemMargin
{
get { return this._itemMargin; }
set { this._itemMargin = value; }
}
private bool _isSelected = false;
/// <summary>
/// 是否選中
/// </summary>
public bool IsSelected
{
get { return this._isSelected; }
set
{
this._isSelected = value;
this.Invalidate();
}
}
private ImageList _smallImageList;
public ImageList SmallImageList
{
get { return this._smallImageList; }
set { this._smallImageList = value; }
}
public NavGroup()
{
InitializeComponent();
this._title = "新建組";
this.BackColor = Color.FromArgb(214,223,247);
SetTitleRectangle();
this._button = new NavBarButton(this);
this._button.Click += new EventHandler
(
delegate(object sender, EventArgs e)
{
if (this._groupState == NavGroupState.collapse)
this.GroupState = NavGroupState.expand;
else
this.GroupState = NavGroupState.collapse;
});
this._items = new NavBarItemCollection(this);
}
public NavGroup(NavBar ownerbar):this()
{
this._ownerBar = ownerbar;
}
/// <summary>
/// 設置標題區域
/// </summary>
private void SetTitleRectangle()
{
this._titleRectangle = new Rectangle(0, 0, this.Width, _titleHeight);
}
/// <summary>
/// 添加項目
/// </summary>
/// <returns></returns>
public NavBarItem AddItem()
{
this._items.Add();
return this._items[this._items.Count - 1];
}
/// <summary>
/// 設置組狀態
/// </summary>
/// <param name="value"></param>
private void SetGroupState(NavGroupState value)
{
if (value == NavGroupState.collapse)
{
this.Height = this._titleHeight;
}
else
{
if (this._items.Count > 0)
{
this.Height = this._items[this._items.Count - 1].Bottom + this._itemSpace;
}
}
this._ownerBar.SetLayOut();
}
/// <summary>
/// 根據新增項布局
/// </summary>
/// <param name="item"></param>
public void SetLayOut(NavBarItem item)
{
this.SuspendLayout();
this.Controls.Add(item);
if (this._items.Count == 0)
{
item.Top = this._titleHeight + 10;
}
else
{
item.Top = this[this._items.Count - 1].Bottom + this.ItempSpace;
}
item.Width = this.Width - 2 * this.ItemMargin;
item.Left = (this.Width - item.Width) / 2;
this.Height = item.Bottom + this.ItempSpace;
this._ownerBar.SetLayOut();
this.ResumeLayout();
}
/// <summary>
/// 重新布局,這個需要完善
/// </summary>
/// <param name="index"></param>
public void SetLayOut(int index)
{
for (int i = index + 1; i < this._items.Count; i++)
{
this._items[i].Top = this._items[i-1].Bottom + this._itemSpace;
}
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
this.IsSelected = true;
this._ownerBar.SelectedIndex = this._groupIndex;
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (this._button.ClientRectangle.Contains(e.Location))
{
this._button.DoClick();
this.Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
SizeF size = e.Graphics.MeasureString(this._title, this.Font);
Font titlefont = new Font(this.Font.FontFamily,this.Font.Size, this.Font.Style | FontStyle.Bold);
//未選中
if (!this._isSelected)
{
LinearGradientBrush brush = new LinearGradientBrush(this._titleRectangle, this._titleStartColor, this._titleEndColor, 0f);
e.Graphics.FillRectangle(brush, this._titleRectangle);
e.Graphics.DrawString(this._title, titlefont, Brushes.Black, this._titleRectangle.X, this._titleRectangle.Top + (this._titleRectangle.Height - size.Height) / 2);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(35, 90, 200)), this._titleRectangle);
e.Graphics.DrawString(this._title, titlefont, Brushes.White, this._titleRectangle.X, this._titleRectangle.Top + (this._titleRectangle.Height - size.Height) / 2);
}
e.Graphics.DrawRectangle(Pens.White, new Rectangle(0, 0, this.Width - 1, this.Height - 1));
//繪制右側原型按鈕
this._button.Draw(e.Graphics);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
SetTitleRectangle();
this._button.SetClientRectangle(this._titleRectangle);
}
}
}
NavBarItem.cs,這裡偷了個懶,該組件包含一個PictureBox和Label組件,PictureBox用來顯示圖標,Lable用來顯示文字
[csharp]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsApplication1
{
public partial class NavBarItem : Control
{
/// <summary>
/// 供外部調用項的點擊事件
/// </summary>
[Browsable(false)]
public event EventHandler ItemClick;
private Rectangle _imageRectangle;
private PictureBox _picbox;
private Label _titlebox;
private NavGroup _ownerGroup;
/// <summary>
/// 所屬組
/// </summary>
public NavGroup OwnerGroup
{
get { return this._ownerGroup; }
set { this._ownerGroup = value; }
}
private int _itemIndex;
public int ItemIndex
{
get { return this._itemIndex; }
set { this._itemIndex = value; }
}
private int _imageIndex = -1;
/// <summary>
/// 圖標的索引
/// </summary>
public int ImageIndex
{
get { return this._imageIndex; }
set
{
if (this._ownerGroup.SmallImageList == null) return;
if (value >= this._ownerGroup.SmallImageList.Images.Count) return;
this._imageIndex = value;
this._picbox.Image = this._ownerGroup.SmallImageList.Images[this._imageIndex];
this.Invalidate();
}
}
private new string _text;
/// <summary>
/// 設置顯示文字
/// </summary>
public new string Text
{
get { return this._text; }
set
{
this._text = value;
this._titlebox.Text = value;
this.Invalidate();
}
}
public NavBarItem()
{
InitializeComponent();
this.AutoSize = false;
this.Height = 22;
this.Cursor = Cursors.Hand;
this._titlebox = new Label();
this._titlebox.Parent = this;
this._titlebox.Dock = DockStyle.Fill;
this._titlebox.TextAlign = ContentAlignment.MiddleLeft;
this._titlebox.MouseHover += new EventHandler(this.OnTitleMouseHover);
this._titlebox.MouseLeave += new EventHandler(this.OnTitleMouseLeave);
this._titlebox.Click += new EventHandler(this.OnTitleClick);
this._picbox = new PictureBox();
this._picbox.Parent = this;
this._picbox.Dock = DockStyle.Left;
this._picbox.Width = this.Height;
this._picbox.SizeMode = PictureBoxSizeMode.CenterImage;
this.Text = "新建項目";
}
public NavBarItem(NavGroup ownergroup)
: this()
{
this._ownerGroup = ownergroup;
}
private void OnTitleClick(object sender, EventArgs e)
{
base.OnClick(e);
if (this.ItemClick != null)
{
this.ItemClick(this, new EventArgs());
}
}
private void OnTitleMouseHover(object sender,EventArgs e)
{
Control c = (Control)sender;
c.ForeColor = Color.Blue;
c.Font = new Font(c.Font.FontFamily, c.Font.Size, c.Font.Style | FontStyle.Underline);
}
private void OnTitleMouseLeave(object sender, EventArgs e)
{
Control c = (Control)sender;
c.ForeColor = SystemColors.ControlText;
c.Font = new Font(c.Font.FontFamily, c.Font.Size, FontStyle.Regular);
}
}
}
NavBarButton.cs
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace WindowsApplication1
{
public class NavBarButton
{
private NavGroup _navgroup;
private Rectangle _clientRectangle;
public Rectangle ClientRectangle
{
get { return this._clientRectangle; }
set { this._clientRectangle = value; }
}
public NavBarButton() { }
public NavBarButton(NavGroup navgroup)
{
this._navgroup = navgroup;
}
public event EventHandler Click;
public void SetClientRectangle(Rectangle parentRect)
{
int i =2;
int w = parentRect.Height;
this._clientRectangle = new Rectangle(parentRect.Width - w + i, parentRect.Top + i, w - 2 * i, w - 2 * i);
}
public void Draw(Graphics g)
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.FillEllipse(Brushes.White, this._clientRectangle);
g.DrawEllipse(Pens.Gray, this._clientRectangle);
Point centerpoint = new Point(this._clientRectangle.X + this._clientRectangle.Width / 2, this._clientRectangle.Y + this._clientRectangle.Height / 2);
int w = this._clientRectangle.Width / 4;
Pen pen = new Pen(Color.Black, 1.6f);
if (this._navgroup.GroupState == NavGroupState.collapse)
{
g.DrawLine(pen, centerpoint.X, centerpoint.Y, centerpoint.X - w, centerpoint.Y - w);
g.DrawLine(pen, centerpoint.X, centerpoint.Y, centerpoint.X + w, centerpoint.Y - w);
g.DrawLine(pen, centerpoint.X, centerpoint.Y + 4, centerpoint.X - w, centerpoint.Y + w - 4);
g.DrawLine(pen, centerpoint.X, centerpoint.Y + 4, centerpoint.X + w, centerpoint.Y + w - 4);
}
else
{
g.DrawLine(pen, centerpoint.X, centerpoint.Y, centerpoint.X - w, centerpoint.Y + w);
g.DrawLine(pen, centerpoint.X, centerpoint.Y, centerpoint.X + w, centerpoint.Y + w);
g.DrawLine(pen, centerpoint.X, centerpoint.Y - 4, centerpoint.X - w, centerpoint.Y + w - 4);
g.DrawLine(pen, centerpoint.X, centerpoint.Y - 4, centerpoint.X + w, centerpoint.Y + w - 4);
}
}
public void DoClick()
{
if (this.Click != null)
{
this.Click(this, new EventArgs());
}
}
}
}
NavGroupCollection.cs
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsApplication1
{
public class NavGroupCollection :List<NavGroup>
{
private NavBar _ownerBar;
public NavGroupCollection(NavBar ownerBar):base()
{
this._ownerBar = ownerBar;
}
public new void Add(NavGroup item)
{
this._ownerBar.SetLayOut(item);
base.Add(item);
item.GroupIndex = this.Count - 1;
item.SmallImageList = this._ownerBar.SmallImageList;
}
public new void Add()
{
NavGroup item = new NavGroup(this._ownerBar);
this.Add(item);
}
}
}
NavBarItemCollection.cs
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsApplication1
{
public class NavBarItemCollection : List<NavBarItem>
{
private NavGroup _ownerGroup;
public NavBarItemCollection(NavGroup ownerGroup):base()
{
this._ownerGroup = ownerGroup;
}
public new void Add(NavBarItem item)
{
this._ownerGroup.SetLayOut(item);
base.Add(item);
item.ItemIndex = this.Count - 1;
}
public new void Add()
{
NavBarItem item = new NavBarItem(this._ownerGroup);
this.Add(item);
}
}
}
NavGroupState.cs
[csharp]
using System;
namespace WindowsApplication1
{
public enum NavGroupState
{
expand,
collapse
}
}
使用,按鈕點擊時,寫如下代碼
[csharp]
NavBarItem item;
navBar1.AddGroup().Title = "控制面板";
item = navBar1[0].AddItem();
item.ImageIndex = 0;
item.Text = "區域選項";
item = navBar1[0].AddItem();
item.ImageIndex = 1;
item.Text = "字體";
item = navBar1[0].AddItem();
item.ImageIndex = 2;
item.Text = "添加硬件";
navBar1.AddGroup().Title = "我的電腦";
item = navBar1[1].AddItem();
item.ImageIndex = 3;
item.Text = "C 盤";
navBar1.AddGroup().Title = "網上鄰居";
item = navBar1[2].AddItem();
item.ImageIndex = 4;
item.Text = "本地連接";
item = navBar1[2].AddItem();
item.ImageIndex = 5;
item.Text = "VPN連接";
navBar1.AddGroup().Title = "我的文檔";
item = navBar1[3].AddItem();
item.ImageIndex = 6;
item.Text = "文檔 A";
item = navBar1[3].AddItem();
item.ImageIndex = 7;
item.Text = "文檔 B";
item = navBar1[3].AddItem();
item.ImageIndex = 8;
item.Text = "文檔 C";
摘自 bdmh的專欄