首先来看看最终效果:
下边我们来一步一步实现:
首先新建一个C# windows application,并在界面上添加一个Pannel控件,拉成合适的形状,如下图:
我们要做的,就是将Button加入到Pannel控件中,并根据鼠标点击移动Button和添加子Button.
第一步,定义一些必要的变量和属性:
private
string
[] _Module;
private string [,] _ChildModule;
private int _ModuleButtonHeight = 50 ;
private int _ChildButtonHeight = 30 ;
///
/// 初始模块
///
public string [] Module
{
get { return _Module; }
set { _Module = value; }
}
///
/// 初始子模块
///
public string [,] ChildModule
{
get { return _ChildModule; }
set { _ChildModule = value; }
}
private string [,] _ChildModule;
private int _ModuleButtonHeight = 50 ;
private int _ChildButtonHeight = 30 ;
///
/// 初始模块
///
public string [] Module
{
get { return _Module; }
set { _Module = value; }
}
///
/// 初始子模块
///
public string [,] ChildModule
{
get { return _ChildModule; }
set { _ChildModule = value; }
}
其中Module数组和ChildModule数组分别是第一层菜单和第二层菜单的Button的Name,_ModuleButtonHeight和_ChildButtonHeight是第一层和第二层菜单的Height.
定义好相关变量和属性了.我们就开始往Panel里面添加东西了.在Form1_Load里面加入下边的代码:
private
void
Form1_Load(
object
sender, EventArgs e)
{
this .panel1.BorderStyle = BorderStyle.FixedSingle;
// 初始化
Module = new string [] { " 初始模块1 " , " 初始模块2 " , " 初始模块3 " };
ChildModule = new string [ 3 , 2 ];
ChildModule[ 0 , 0 ] = " 子模块1 " ;
ChildModule[ 0 , 1 ] = " 子模块2 " ;
ChildModule[ 1 , 0 ] = " 子模块3 " ;
ChildModule[ 1 , 1 ] = " 子模块4 " ;
ChildModule[ 2 , 0 ] = " 子模块5 " ;
ChildModule[ 2 , 1 ] = "" ;
for ( int i = 0 ; i < Module.Length; i ++ )
{
// 增加模块Button
Button btn = new Button();
btn.FlatStyle = FlatStyle.Flat;
btn.Width = this .panel1.Width;
btn.Height = _ModuleButtonHeight;
btn.Name = string .Format( " Button{0} " , i.ToString());
btn.Text = Module[i];
btn.Top = _ModuleButtonHeight * i;
btn.Click += new EventHandler(btn_Click);
this .panel1.Controls.Add(btn);
}
}
{
this .panel1.BorderStyle = BorderStyle.FixedSingle;
// 初始化
Module = new string [] { " 初始模块1 " , " 初始模块2 " , " 初始模块3 " };
ChildModule = new string [ 3 , 2 ];
ChildModule[ 0 , 0 ] = " 子模块1 " ;
ChildModule[ 0 , 1 ] = " 子模块2 " ;
ChildModule[ 1 , 0 ] = " 子模块3 " ;
ChildModule[ 1 , 1 ] = " 子模块4 " ;
ChildModule[ 2 , 0 ] = " 子模块5 " ;
ChildModule[ 2 , 1 ] = "" ;
for ( int i = 0 ; i < Module.Length; i ++ )
{
// 增加模块Button
Button btn = new Button();
btn.FlatStyle = FlatStyle.Flat;
btn.Width = this .panel1.Width;
btn.Height = _ModuleButtonHeight;
btn.Name = string .Format( " Button{0} " , i.ToString());
btn.Text = Module[i];
btn.Top = _ModuleButtonHeight * i;
btn.Click += new EventHandler(btn_Click);
this .panel1.Controls.Add(btn);
}
}
上边代码是根据Module定义的数目往Pannel里面塞Button,这些Button就是第一层的菜单项.当我们点击这些Button的时候,就要显示子菜单项.所以当点击Button的时候触发的事件需要做如下处理:
private
void
btn_Click(
object
sender, EventArgs e)
{
// 标志是否找到用户点击的Button
bool findOutStatus = false ;
// 清除上一次操作加载的子菜单项
for ( int i = 0 ; i < this .panel1.Controls.Count; i ++ )
{
if ( this .panel1.Controls[i].GetType().Name == " Panel " )
{
this .panel1.Controls.RemoveAt(i);
}
}
for ( int i = 0 ; i < this .panel1.Controls.Count; i ++ )
{
if ( this .panel1.Controls[i].GetType().Name == " Button " )
{
// 重新定义各个button位置
if ( ! findOutStatus)
{
this .panel1.Controls[i].Top = _ModuleButtonHeight * i;
}
else
{
this .panel1.Controls[i].Top = this .panel1.Height - (_ModuleButtonHeight * (Module.Length - i));
}
// 找到所点击的Button,在其下加载子菜单
if ( this .panel1.Controls[i].Name == ((Button)sender).Name)
{
findOutStatus = true ;
Panel panel = new Panel();
panel.BackColor = Color.AliceBlue;
panel.Top = _ModuleButtonHeight * (i + 1 );
panel.Width = this .panel1.Width;
panel.Height = this .panel1.Height - _ModuleButtonHeight * Module.Length;
this .panel1.Controls.Add(panel);
for ( int j = 0 ; j < ChildModule.Length / Module.Length; j ++ )
{
if ( ! string .IsNullOrEmpty(ChildModule[i, j]))
{
Button btn = new Button();
btn.FlatStyle = FlatStyle.Flat;
btn.Top = _ChildButtonHeight * j;
btn.Width = this .panel1.Width;
btn.Height = _ChildButtonHeight;
btn.Name = string .Format( " ChildButton{0}_{1} " , i.ToString(), j.ToString());
btn.Text = ChildModule[i, j];
btn.Click += new EventHandler(btnChild_Click);
panel.Controls.Add(btn);
}
}
}
}
}
}
{
// 标志是否找到用户点击的Button
bool findOutStatus = false ;
// 清除上一次操作加载的子菜单项
for ( int i = 0 ; i < this .panel1.Controls.Count; i ++ )
{
if ( this .panel1.Controls[i].GetType().Name == " Panel " )
{
this .panel1.Controls.RemoveAt(i);
}
}
for ( int i = 0 ; i < this .panel1.Controls.Count; i ++ )
{
if ( this .panel1.Controls[i].GetType().Name == " Button " )
{
// 重新定义各个button位置
if ( ! findOutStatus)
{
this .panel1.Controls[i].Top = _ModuleButtonHeight * i;
}
else
{
this .panel1.Controls[i].Top = this .panel1.Height - (_ModuleButtonHeight * (Module.Length - i));
}
// 找到所点击的Button,在其下加载子菜单
if ( this .panel1.Controls[i].Name == ((Button)sender).Name)
{
findOutStatus = true ;
Panel panel = new Panel();
panel.BackColor = Color.AliceBlue;
panel.Top = _ModuleButtonHeight * (i + 1 );
panel.Width = this .panel1.Width;
panel.Height = this .panel1.Height - _ModuleButtonHeight * Module.Length;
this .panel1.Controls.Add(panel);
for ( int j = 0 ; j < ChildModule.Length / Module.Length; j ++ )
{
if ( ! string .IsNullOrEmpty(ChildModule[i, j]))
{
Button btn = new Button();
btn.FlatStyle = FlatStyle.Flat;
btn.Top = _ChildButtonHeight * j;
btn.Width = this .panel1.Width;
btn.Height = _ChildButtonHeight;
btn.Name = string .Format( " ChildButton{0}_{1} " , i.ToString(), j.ToString());
btn.Text = ChildModule[i, j];
btn.Click += new EventHandler(btnChild_Click);
panel.Controls.Add(btn);
}
}
}
}
}
}
点击第一层菜单项,就根据点击的Button相应调整各个Button的位置,并在其下填充一个pannel控件,在这个pannel控件里面填充子菜单项.
当填充完成的时候,就实现了类似QQ面板的功能了.在这个Click事件里面更可以加上声音效果,或者对Button和Form贴一些图片.就更像QQ面板.
当点击子菜单,则会触发相应事件:
private
void
btnChild_Click(
object
sender, EventArgs e)
{
MessageBox.Show( string .Format( " 你点击了 \ " { 0 }\ " 按钮! " , ((Button)sender).Name), " 系统提示 " , MessageBoxButtons.OK, MessageBoxIcon.Information);
}
{
MessageBox.Show( string .Format( " 你点击了 \ " { 0 }\ " 按钮! " , ((Button)sender).Name), " 系统提示 " , MessageBoxButtons.OK, MessageBoxIcon.Information);
}
完整源代码下载: http://files.cnblogs.com/KenBlove/QQPanel.7z
(本代码修改自网络上相关代码)