【IT168技术】自定义Tab按钮(如图所示)
我们的tab按钮左部是文字;右部是关闭按钮;此按钮有两种状态:选中和未选中。未选中的按钮鼠标滑上背景色会变为淡蓝色;选中的按钮背景色是黄色;关闭按钮鼠标滑上去是深黄色。
控件中涉及的属性和公开的事件属性
/// <summary>
/// Tab标题
/// </summary>
public string Caption;
/// <summary>
/// 是否选中
/// </summary>
bool IsSelected = true;
/// <summary>
/// 文字的颜色
/// </summary>
Color StrColor = Color.Black;
/// <summary>
/// 宽度
/// </summary>
int StrWidth;
/// <summary>
/// 选中事件
/// </summary>
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public event EventHandler OnSelect;
/// <summary>
/// 单击关闭按钮事件
/// </summary>
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public event EventHandler OnClose;
/// Tab标题
/// </summary>
public string Caption;
/// <summary>
/// 是否选中
/// </summary>
bool IsSelected = true;
/// <summary>
/// 文字的颜色
/// </summary>
Color StrColor = Color.Black;
/// <summary>
/// 宽度
/// </summary>
int StrWidth;
/// <summary>
/// 选中事件
/// </summary>
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public event EventHandler OnSelect;
/// <summary>
/// 单击关闭按钮事件
/// </summary>
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public event EventHandler OnClose;
注释还是比较清楚的,就不多说了
接着看这个控件自己的事件
/// <summary>
/// 鼠标移入事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_MouseEnter(object sender, EventArgs e)
{
if (!IsSelected)
{
this.BackColor = ColorTranslator.FromHtml("#4D6082");
}
}
/// <summary>
/// 鼠标移出事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_MouseLeave(object sender, EventArgs e)
{
if (!IsSelected)
{
this.BackColor = ColorTranslator.FromHtml("#293955");
}
}
/// <summary>
/// 鼠标移动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_MouseMove(object sender, MouseEventArgs e)
{
var flag = IsMouseOnClosePoint();
if (flag)
{
DrawControl(Color.Black, Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(232)))), ((int)(((byte)(166))))));
}
else
{
DrawControl(StrColor, this.BackColor);
}
}
/// <summary>
/// 重绘事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_Paint(object sender, PaintEventArgs e)
{
DrawControl(StrColor, this.BackColor);
}
/// 鼠标移入事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_MouseEnter(object sender, EventArgs e)
{
if (!IsSelected)
{
this.BackColor = ColorTranslator.FromHtml("#4D6082");
}
}
/// <summary>
/// 鼠标移出事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_MouseLeave(object sender, EventArgs e)
{
if (!IsSelected)
{
this.BackColor = ColorTranslator.FromHtml("#293955");
}
}
/// <summary>
/// 鼠标移动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_MouseMove(object sender, MouseEventArgs e)
{
var flag = IsMouseOnClosePoint();
if (flag)
{
DrawControl(Color.Black, Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(232)))), ((int)(((byte)(166))))));
}
else
{
DrawControl(StrColor, this.BackColor);
}
}
/// <summary>
/// 重绘事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_Paint(object sender, PaintEventArgs e)
{
DrawControl(StrColor, this.BackColor);
}
移入和移出事件都是要触发移动事件的,移动事件要先判断鼠标所在的位置,是不是出于关闭按钮位置; 然后再根据鼠标的位置以不同的颜色绘制控件。
下面看绘制控件和判断鼠标位置的相关方法
/// <summary>
/// 重写创建事件
/// </summary>
protected override void OnCreateControl()
{
base.OnCreateControl();
var g = this.CreateGraphics();
StrWidth = (int)g.MeasureString(Caption, SystemFonts.DefaultFont).Width;
g.Dispose();
this.Width = StrWidth + 24;
}
/// <summary>
/// 绘制控件
/// </summary>
/// <param name="fore"></param>
/// <param name="bg"></param>
void DrawControl(Color fore, Color bg)
{
var g = this.CreateGraphics();
g.DrawString(Caption, SystemFonts.DefaultFont, new SolidBrush(StrColor), new PointF(3, 8));
var p = new Pen(fore, (float)1);
g.FillRectangle(new SolidBrush(bg), new Rectangle(StrWidth + 6, 7, 13, 13));
g.TranslateTransform(StrWidth + 12, 13);
g.RotateTransform(45);
for (var i = 0; i < 4; i++)
{
g.RotateTransform(90);
g.DrawLine(p, 0, 0, 6, 0);
}
g.ResetTransform();
p.Dispose();
g.Dispose();
}
/// <summary>
/// 鼠标位置
/// </summary>
/// <returns></returns>
public bool IsMouseOnClosePoint()
{
var p = this.PointToClient(MousePosition);
var crx = new Rectangle(StrWidth + 3, 3, 16, 16);
return crx.Contains(p);
}
/// 重写创建事件
/// </summary>
protected override void OnCreateControl()
{
base.OnCreateControl();
var g = this.CreateGraphics();
StrWidth = (int)g.MeasureString(Caption, SystemFonts.DefaultFont).Width;
g.Dispose();
this.Width = StrWidth + 24;
}
/// <summary>
/// 绘制控件
/// </summary>
/// <param name="fore"></param>
/// <param name="bg"></param>
void DrawControl(Color fore, Color bg)
{
var g = this.CreateGraphics();
g.DrawString(Caption, SystemFonts.DefaultFont, new SolidBrush(StrColor), new PointF(3, 8));
var p = new Pen(fore, (float)1);
g.FillRectangle(new SolidBrush(bg), new Rectangle(StrWidth + 6, 7, 13, 13));
g.TranslateTransform(StrWidth + 12, 13);
g.RotateTransform(45);
for (var i = 0; i < 4; i++)
{
g.RotateTransform(90);
g.DrawLine(p, 0, 0, 6, 0);
}
g.ResetTransform();
p.Dispose();
g.Dispose();
}
/// <summary>
/// 鼠标位置
/// </summary>
/// <returns></returns>
public bool IsMouseOnClosePoint()
{
var p = this.PointToClient(MousePosition);
var crx = new Rectangle(StrWidth + 3, 3, 16, 16);
return crx.Contains(p);
}
我们在创建控件的时候得到了文本的宽度,根据这个宽度来绘制控件文本和关闭按钮的位置。
我们在属性里为这个控件定义了事件的handler
下面看看这些handler是怎么触发的
/// <summary>
/// 取消选中
/// </summary>
public void DisSelectMe()
{
IsSelected = false;
this.BackColor = ColorTranslator.FromHtml("#293955");
StrColor = Color.White;
DrawControl(StrColor, this.BackColor);
}
/// <summary>
/// 选择中
/// </summary>
public void SelectMe()
{
IsSelected = true;
this.BackColor = SystemColors.Info;
StrColor = Color.Black;
DrawControl(StrColor, this.BackColor);
}
/// <summary>
/// 触发自定义事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_Click(object sender, EventArgs e)
{
var flag = IsMouseOnClosePoint();
if (flag)
{
OnClose(this, EventArgs.Empty);
}
else
{
if (IsSelected)
{
return;
}
OnSelect(this, EventArgs.Empty);
SelectMe();
}
}
/// 取消选中
/// </summary>
public void DisSelectMe()
{
IsSelected = false;
this.BackColor = ColorTranslator.FromHtml("#293955");
StrColor = Color.White;
DrawControl(StrColor, this.BackColor);
}
/// <summary>
/// 选择中
/// </summary>
public void SelectMe()
{
IsSelected = true;
this.BackColor = SystemColors.Info;
StrColor = Color.Black;
DrawControl(StrColor, this.BackColor);
}
/// <summary>
/// 触发自定义事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TabBTN_Click(object sender, EventArgs e)
{
var flag = IsMouseOnClosePoint();
if (flag)
{
OnClose(this, EventArgs.Empty);
}
else
{
if (IsSelected)
{
return;
}
OnSelect(this, EventArgs.Empty);
SelectMe();
}
}
到此为止完成了tab按钮的制作。