效果:
描述:
这是一个可折叠的菜单导航,主要是由panel、picturebox、label完成,界面的颜色用来区分一下各个组合控件,便于调试。
首先,首先是ImageButton:
这个是由PictureBox和Label构成。
1.文字部分的居中需要设置label的宽度为父容器的宽度。
2.图片设置 picBox.SizeMode = PictureBoxSizeMode.StretchImage
然后是单个的菜单 命名为:ButtonGroup:
顶部灰色的是一个label,绿色里面的是一个包含ImageButton的列表。
1.顶部这个label注册了一个click事件,是为了完成点击它的时候会展开。
最后是整个的菜单,就是由ButtonGroup组成的一个list,我给它命名为:CustomNavBar。
这里需要注意的是:
事件的封装,像这种自定义控件,都是要定义自定义事件,并且把它暴露出来,元控件触发的时候,才触发这个暴露出来的控件。代码类似这种:
private void PicBoxClick(object sender,EventArgs args)
{
PictureBoxClick?.Invoke(sender, this.text);
}
PicBoxClick是PictureBox控件的原生Click事件,PictureBoxClick是我们自己定义的事件,这个事件需要到控件外部注册,就像这样:
for (int i = 0; i < _listImageButton.Count; i++)
{
var imgButton = _listImageButton[i];
imgButton.Top = i * imgButton.Height;
imgButton.Left = 0;
imgButton.PictureBoxClick += ImgButton_PictureBoxClick;
ButtonArea.Controls.Add(imgButton);
}
这段代码中,_listImageButton是属于ButtonGroup控件里的集合,这样做,最终点击PictureBox的时候,其实是调用ImgButton_PictureBoxClick这个方法里的内容。
假如这个ButtonGroup已经是最外层的自定义控件了,那么这个ImgButton_PictureBoxClick就属于供这个完整的自定义控件使用人也就是客户自己自定义的事件了,这个里面的代码就可以根据不同的客户,内容就可以不同了。
因为这个控件最外层的自定义控件是CustomNavBar,所以在CustomNavbar里还自定义了一个相同委托的事件:
public delegate void ImageButtonClick(object o,string moduleName);
public event ImageButtonClick NavButtonClick;
这代码也是我从其他地方下载的,然后自己看了一篇,在自己敲的。敲的过程中,了解到了内部类的使用,最大的收获是:一般窗体都是要有partial修饰的,而InitializeComponent()方法都是放在自动生成的代码里的,做这个控件的时候,我还是自己第一次这样通过写代码的方式来初始化一个控件。
代码:
public partial class CustomNavBar : UserControl
{
public CustomNavBar()
{
InitializeComponent();
InitializeButtonGroup();
pnlMain.BackColor = Color.DarkOliveGreen;
ResetMenu();
}
private string _jsonString;
///
///暴露接口,可从外部(数据库)获得菜单的信息
///
public string JsonString
{
get { return _jsonString; }
set { _jsonString = value; }
}
private List listGroup;
private int currentItemIndex;
public delegate void ImageButtonClick(object o,string moduleName);
public event ImageButtonClick NavButtonClick;
public void InitializeButtonGroup()
{
listGroup = new List() {
new ButtonGroup("欢迎使用",
new List()
{
new ImageButton("欢迎使用",Resources.LogoMain),
new ImageButton("员工信息管理",Resources.LogoManageEmployee)
}),
new ButtonGroup("系统设置",
new List(){
new ImageButton("部门管理", Resources.LogoManageDepartment)}),
new ButtonGroup("退出系统",null)
};
ButtonGroup bgPre=null;
int sum = 0;
for (int i = 0; i < listGroup.Count; i++)
{
int height = bgPre == null ? 0 : bgPre.Height;
sum += height;
var buttonGroup = listGroup[i];
buttonGroup.Tag = i;
buttonGroup.SetButtonLocation();
buttonGroup.ImageButtonClick += new ImageButtonClick(NavClick);
buttonGroup.Left = 0;
buttonGroup.Top = sum;
buttonGroup.ItemMeunClick += ButtonGroup_ItemMeunClick;
this.pnlMain.Controls.Add(buttonGroup);
bgPre = buttonGroup;
}
}
private void NavClick(object sender,string moduleName)
{
NavButtonClick?.Invoke(sender, moduleName);
}
private void ButtonGroup_ItemMeunClick(object sender, EventArgs e)
{
Label lblItem = sender as Label;
currentItemIndex = 0;
if (lblItem != null)
{
ButtonGroup bg = lblItem.Parent as ButtonGroup;
if (bg != null)
{
currentItemIndex = Convert.ToInt32(bg.Tag);
}
}
ResetMenu();
}
private void ResetMenu()
{
if (listGroup != null && listGroup.Count > 0)
{
int barHeight = 22;
int totalHeight = pnlMain.Height;
for (int n = 0; n < listGroup.Count; n++)
{
ButtonGroup buttonGroup = listGroup[n];
int thisIndex = Convert.ToInt32(buttonGroup.Tag);
if (thisIndex <= currentItemIndex)
{
buttonGroup.Top =n * barHeight;
}
else
{
buttonGroup.Top = totalHeight - (listGroup.Count-n) * barHeight;
}
if (thisIndex == currentItemIndex)
{
buttonGroup.Height = totalHeight - (listGroup.Count - 1) * barHeight;
}
else
{
buttonGroup.Height = barHeight;
}
}
}
}
#region ButtonGroup
public class ButtonGroup : UserControl
{
private Label lblItem = new Label();
private string text;
private Panel ButtonArea = new Panel();
public event EventHandler ItemMeunClick;
public event ImageButtonClick ImageButtonClick;
public ButtonGroup(string txt,List listImageButton)
{
this.text = txt;
this._listImageButton = listImageButton;
this.Initialize();
}
private List _listImageButton;
public List ListImageButton
{
get { return _listImageButton; }
set { _listImageButton = value; }
}
public void Initialize()
{
lblItem.Text = this.text;
lblItem.Height = 22;
lblItem.Width = 156;
lblItem.TextAlign = ContentAlignment.MiddleCenter;
lblItem.BackColor = Color.DarkGray;
lblItem.ForeColor = Color.DarkRed;
lblItem.Cursor = Cursors.Hand;
lblItem.Click += LblItem_Click;
this.Width = 156;
this.BackColor = Color.DarkOliveGreen;
this.Controls.Add(lblItem);
this.Controls.Add(ButtonArea);
}
private void LblItem_Click(object sender, EventArgs e)
{
ItemMeunClick?.Invoke(sender, e);
}
public void SetButtonLocation()
{
ButtonArea.Location = new Point(0, 22);
int buttonCount = _listImageButton == null ? 0 : _listImageButton.Count;
int Height = 62;
//ButtonArea.BackColor = Color.Red;
ButtonArea.Size = new Size(156, buttonCount * Height);
if (_listImageButton != null && _listImageButton.Count > 0)
{
for (int i = 0; i < _listImageButton.Count; i++)
{
var imgButton = _listImageButton[i];
imgButton.Top = i * imgButton.Height;
imgButton.Left = 0;
imgButton.PictureBoxClick += ImgButton_PictureBoxClick;
ButtonArea.Controls.Add(imgButton);
}
}
this.Height = lblItem.Height + ButtonArea.Height;
}
private void ImgButton_PictureBoxClick(object o, string moduleName)
{
ImageButtonClick?.Invoke(o, moduleName);
}
}
#endregion
#region ImageButton
public class ImageButton : UserControl
{
private string text;
private Image img;
private PictureBox picBox=new PictureBox();
private Label lblText = new Label();
public event ImageButtonClick PictureBoxClick;
public ImageButton(string txt, Image image)
{
this.text = txt;
this.img = image;
this.InitialImageButtonControl();
}
public void InitialImageButtonControl()
{
picBox.Size = new Size(40, 40);
picBox.Left = 57;
picBox.Top = 0;
picBox.Image = this.img;
picBox.Anchor = AnchorStyles.Top;
picBox.SizeMode = PictureBoxSizeMode.StretchImage;
picBox.Cursor = Cursors.Hand;
picBox.Click += new EventHandler(PicBoxClick);
lblText.Width = 156;
lblText.Height = 22;
lblText.Location = new Point(0, 40);
lblText.Text = this.text;
lblText.TextAlign = ContentAlignment.MiddleCenter;
lblText.BackColor = Color.DarkOliveGreen;
lblText.ForeColor = Color.DarkGray;
lblText.Cursor = Cursors.Hand;
this.Height = picBox.Height + lblText.Height;
this.Controls.Add(picBox);
this.Controls.Add(lblText);
}
private void PicBoxClick(object sender,EventArgs args)
{
PictureBoxClick?.Invoke(sender, this.text);
}
}
#endregion
}