十一前就开始准备做了,不过一到放假就发现自己懒了,哈哈,现在就把效果图片发上来给大家看看,并谈谈关键部分的代码.
一.设计时效果

二.运行时效果
1)有3个选项页时的运行效果.

2).选项页比较多的时候,在底端对齐后的效果.

3).变换了渐变色后的效果.

三.谈谈设计的实现原理:
制作这个控件需要由2个主要的部分组成.一是容器,二是容器里面显示的选项页.选项页是一个继承自panel的控件(JcsPage),提供了2种布局方式,也就是我们在设计时期图片中看到2种布局(一种是加号展开,减号折叠,另一种是双箭头向下展开,双箭头向上折叠),主要是在onpaint方法里对不同的布局做相应的处理,同时需要重写按钮相应事件,对鼠标位置是否在指定区域(双箭头或加减号所在的矩形区域)的判断,如果在这个区域将引发一事件.容器控件是一个继承自ContainerControl的控件,主要提供对容器内元素的管理以及布局的处理,关键的代码是如何对高度变化的元素做相应位置上的有效调整.另外,因为设置了autoscroll为真,所以,在出现纵向滚动条的时候,要将所有元素的宽度适当地缩小到(容器工作区 - 滚动条宽度)的值.如果哪位朋友有兴趣或需要源代码,可以联系我(heqiumie@tom.com ),不过因为开发的程序大多数都会适当的(其实很少)收取一些费用,所以也请大家谅解!
部分源代码:
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Drawing;
using
System.Data;
using
System.Text;
using
System.Windows.Forms;
using
System.Windows.Forms.VisualStyles;
using
System.Drawing.Drawing2D;
namespace
JcsControlLibrary

...
{
public class BaseContainerPanel : ContainerControl

...{

Fields#region Fields
private bool _isfirst = true; //是否为第一次排序
private static ToolStripProfessionalRenderer renderer;
private CollectionEvents Items = new CollectionEvents();
private int _expandpagecount = 0; //展开page的数量
#endregion


Events#region Events

public event EventHandler ThemeChanged;

#endregion


Init#region Init

//static BaseStyledPanel()
//{
// renderer = new ToolStripProfessionalRenderer();
//}
public BaseContainerPanel()

...{
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
renderer = new ToolStripProfessionalRenderer();
}

#endregion


Methods#region Methods

protected override void OnSystemColorsChanged(EventArgs e)

...{
base.OnSystemColorsChanged(e);
UpdateRenderer();
Invalidate();
}

protected virtual void OnThemeChanged(EventArgs e)

...{
if (ThemeChanged != null)
ThemeChanged(this, e);
}

private void UpdateRenderer()

...{
if (!UseThemes)

...{
renderer.ColorTable.UseSystemColors = true;
}
else

...{
renderer.ColorTable.UseSystemColors = false;
}
}

#endregion


Props#region Props

[Browsable(false)]
public ToolStripProfessionalRenderer ToolStripRenderer

...{

get ...{ return renderer; }
}
//是否使用主题
[DefaultValue(true)]
[Browsable(false)]
public bool UseThemes

...{
get

...{
return VisualStyleRenderer.IsSupported && VisualStyleInformation.IsSupportedByOS && Application.RenderWithVisualStyles;
}
}

#endregion
private void InitGetExpandPage()

...{
this._expandpagecount = 0;
for (int i = 0; i < this.Controls.Count; i++)

...{
JcsPage page = (JcsPage)this.Controls[i];
if (page.IsExpand)

...{
this._expandpagecount++;
}
}
}

/**//// <summary>
/// 是否全部展开
/// </summary>
/// <returns>全部展开:TRUE,否则:FALSE</returns>
private bool GetIsAllExpand()

...{
if (this._expandpagecount == this.Controls.Count)

...{
return true;
}
else

...{
return false;
}
}
public void AddPage(JcsPage Pageitem)

...{
AddPage( Pageitem, false);
}
public void AddPage( JcsPage Pageitem, bool autoSelect)

...{
Pageitem.Width = this.ClientRectangle.Width ;
Pageitem.IsExpand = false;
if (this.Controls.Contains(Pageitem ))
return ;
Items.Add(Pageitem);
Pageitem.Buttonclickevent += new JcsPage.Buttonclick(Pageitem_Buttonclickevent);
this.Controls.Add(Pageitem);
InitGetExpandPage();
UpdateLayout();
}
private JcsPage _currentpage;
void Pageitem_Buttonclickevent(object sender)

...{
if (sender != null)

...{
_currentpage = (JcsPage)sender;
if (_currentpage.IsExpand)

...{
this._expandpagecount++;
//if (this.Controls.IndexOf(_currentpage) == this.Controls.Count - 1)
//{
// if (_currentpage.Bottom < this.Bottom && _currentpage.Top > this.Top )
// {
// _currentpage.Height += this.Bottom - _currentpage.Bottom;
// }
//}
}
else

...{
this._expandpagecount--;
}
}
this.UpdateLayout();
}

private void UpdateLayout()

...{

/**/////一个都没有展开的情况
//if (this._expandpagecount == 0)
//{
// if (!this.VScroll)
// {
// int sumtop = 0;
// for (int i = 0; i < Items.Count; i++)
// {
// JcsPage page = (JcsPage)Items[i];
// page.Left = 0;
// page.Top = sumtop;
// page.Width = this.ClientRectangle.Width;
// sumtop += page.Height;
// }
// }
//}
//else
//{
// for (int i = 0; i < Items.Count; i++)
// {
// JcsPage page = (JcsPage)Items[i];
// if (i == 0)
// {
// page.Dock = DockStyle.Top;
// }
// else
// {
// page.Dock = DockStyle.Bottom;
// }
// }
//}
if (Items.Count == 0)
return;

int index = 0;
if (_currentpage != null)

...{
index = this.Controls.IndexOf(_currentpage);
}
if (_isfirst)

...{
((JcsPage)Items[index]).Top = 0;
_isfirst = false;
}
int oldtop = ((JcsPage)Items[index]).Top; ;
int sumtop = oldtop;
for (int i = index; i < Items.Count; i++)

...{
JcsPage page = (JcsPage)Items[i];
page.Left = 0;
page.Top = sumtop;
page.Width = this.ClientRectangle.Width;
sumtop += page.Height;
//if (this.Controls.IndexOf(_currentpage) == this.Controls.Count - 1)
//{
// if (_currentpage.Bottom < this.Bottom && _currentpage.Top > this.Top)
// {
// _currentpage.Height += this.Bottom - _currentpage.Bottom;
// }
//}
if (this.Controls.IndexOf(page) == this.Controls.Count - 1)

...{
if (page.Bottom < this.Bottom && page.Bottom >= 0 && page.IsExpand)

...{
page.Height += this.Bottom - page.Bottom;
}
}
}
}
protected override void OnClientSizeChanged(EventArgs e)

...{
base.OnClientSizeChanged(e);
for (int i = 0; i < Items.Count; i++)

...{
JcsPage page = (JcsPage)Items[i];
page.Width = this.ClientRectangle.Width;
}
}
protected override void OnPaint(PaintEventArgs e)

...{
base.OnPaint(e);
Graphics g = e.Graphics;
using(Pen p= new Pen(Color.Gray))

...{
g.DrawRectangle(p, 0, 0, this.Width-2, this.Height);
}
}
}
}