WinForm原生TacControl定制标签样式
因为工作需要一个UI所使用的TabControl标签页效果需要定制实现,开始在网上找到一个实现的Demo,原理是控件通过绘制方法实现定制的目的,绘制过程就是使用GDI+画图的过程,包装一个控件供复用
- 首先,在控件构造方法中设定控件的样式为用户绘制相关样式
声明控件由用户自行绘制,开打双缓冲防闪烁,全部绘制均在wm_paint消息中,控件尺寸变化时进行重绘
base.SetStyle(
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw, true);
- 之后,设置标签页的样式
正常按标签的文本伸缩尺寸
this.SizeMode = TabSizeMode.Normal;
this.Alignment = TabAlignment.Top;
- 全部标签定制的效果均在OnPaint方法内实现
逐个标签页绘制,先画背景,再画文本,最后边框,边框实现上为一个梯形,使用Path对象实现
以下为Demo类源代码
public class PaintHeadTabControl : TabControl
{
private Color controlBackColor = Color.White;
private Color tabPageBorderColor = Color.LightGray;
private Color headNormalBorderColor = Color.LightGray;
private Color headCurrentBorderColor = Color.FromArgb(75, 161, 239);
private Color currentBgColor = Color.FromArgb(75, 161, 239);
private Color normalBgColor = Color.FromArgb(248, 249, 253);
private Font currentFont = new Font("微软雅黑", 11, FontStyle.Bold, GraphicsUnit.Pixel);
private Color currentForeColor = Color.White;
private Font normalFont = new Font("微软雅黑", 11, FontStyle.Regular, GraphicsUnit.Pixel);
private Color normalForeColor = Color.FromArgb(106, 106, 106);public PaintHeadTabControl()
{
base.SetStyle(
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw, true);// deafult head size
this.SizeMode = TabSizeMode.Normal;
this.Alignment = TabAlignment.Top;
//this.ItemSize = new Size(90, 25);
}[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new TabAlignment Alignment
{
get { return base.Alignment; }
set { base.Alignment = value; }
}[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new TabSizeMode SizeMode
{
get { return base.SizeMode; }
set { base.SizeMode = value; }
}[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Size ItemSize
{
get { return base.ItemSize; }
set { base.ItemSize = value; }
}protected override void Dispose(bool disposing)
{
base.Dispose(disposing);if (disposing)
{
if (this.currentFont != null)
{
this.currentFont.Dispose();
this.currentFont = null;
}if (this.normalFont != null)
{
this.normalFont.Dispose();
this.normalFont = null;
}
}
}
/// <summary>
/// on paint draw head
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);var g = e.Graphics;
// anti alias
g.SmoothingMode = SmoothingMode.AntiAlias;// draw tab control bg
this.DrawControlBg(g);// head
for (int index = 0; index < this.TabCount; index++)
{
var tab = this.TabPages[index];
var headbounds = this.GetTabRect(index);// is current
var isCurrent = index == this.SelectedIndex;// get draw path
using (var path = this.GetHeadDrawPath(headbounds))
{
// bg
this.DrawHeadBg(g, isCurrent, path);// text
this.DrawHeadText(g, isCurrent, tab.Text, headbounds);// border
this.DrawHeadBorder(g, isCurrent, path);
}
}// tab border
this.DrawTabPageBorder(g);
}private void DrawControlBg(Graphics g)
{
using (var br = new SolidBrush(this.controlBackColor))
{
g.FillRectangle(br, this.ClientRectangle);
}
}private void DrawHeadBg(Graphics g, bool isCurrent, GraphicsPath path)
{
if (isCurrent)
{
using (var br = new System.Drawing.SolidBrush(currentBgColor))
{
g.FillPath(br, path);
}
}
else
{
using (var br = new System.Drawing.SolidBrush(normalBgColor))
{
g.FillPath(br, path);
}
}
}private void DrawHeadText(Graphics g, bool isCurrent, string text, Rectangle headbounds)
{
using (var format = new System.Drawing.StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center,
Trimming = StringTrimming.EllipsisCharacter
})
{
if (isCurrent)
{
using (var br = new SolidBrush(this.currentForeColor))
{
g.DrawString(text, this.currentFont, br, headbounds, format);
}
}
else
{
using (var br = new SolidBrush(this.normalForeColor))
{
g.DrawString(text, this.normalFont, br, headbounds, format);
}
}
}
}private void DrawHeadBorder(Graphics g, bool isCurrent, GraphicsPath path)
{
if (isCurrent)
{
using (var borderPen = new Pen(this.headCurrentBorderColor))
{
g.DrawPath(borderPen, path);
}
}
else
{
using (var borderPen = new Pen(this.headNormalBorderColor))
{
g.DrawPath(borderPen, path);
}
}
}private void DrawTabPageBorder(Graphics g)
{
if (this.SelectedIndex > -1)
{
var tab = this.TabPages[this.SelectedIndex];
var bounds = tab.Bounds;using (var pen = new Pen(this.tabPageBorderColor, 2))
{
g.DrawRectangle(pen, bounds);
}
}
}private GraphicsPath GetHeadDrawPath(Rectangle headBounds)
{
var path = new System.Drawing.Drawing2D.GraphicsPath();
var conerWidth = Math.Min(15, headBounds.Width / 6);
var topConner = headBounds.Left + (headBounds.Width - conerWidth);
path.AddLines(new Point[]{
new Point(){ X = headBounds.Left + 2, Y = headBounds.Y },
new Point(){ X = topConner, Y = headBounds.Y },
new Point(){ X = headBounds.Right, Y = headBounds.Bottom+1 },
new Point(){ X = headBounds.Left + 2, Y = headBounds.Bottom+1 },
new Point(){ X = headBounds.Left + 2, Y = headBounds.Y },
});return path;
}
}

浙公网安备 33010602011771号