在工程化的應用中, 爲了取得良好的風格或者具有自身特色的界面,一個重要的方面就是要重繪控件, 菜單作爲比較重要的資源,經常在軟件中使用,設計漂亮的菜單有助於建立良好的商業化軟件。
C#的提供了MenuStrip菜單控件,爲了重繪菜單,需要進行建立以MenuStrip爲基類的繼承類,而C#中,與菜單相關的重寫函數均位於ToolStripRenderer,也要重寫以ToolStripRenderer作爲基類的繼承類,在菜單MenuStrip繼承類中進行調用。
classCustomMenuStrip : MenuStrip
{
privateColor menu_Color = Color.FromArgb(200, 186, 209, 239);
privateColor selected_Color = Color.FromArgb(200, 175,150,10);
privateColor board_Color = Color.LightGray;
privateColor image_Color = Color.FromArgb(255, 0, 0, 128);
privateColor separator_color = Color.Black;
public CustomMenuStrip()
{
this.Renderer = newCustomProfessionalRenderer(menu_Color, selected_Color, board_Color, image_Color,separator_color);
}
publicvoid SetColor(Color mColor, Color selColor, Color bColor, Color iColor, Color sColor)
{
menu_Color = mColor;
selected_Color = selColor;
board_Color = bColor;
image_Color = iColor;
separator_color = sColor;
this.Renderer = newCustomProfessionalRenderer(menu_Color, selected_Color, board_Color, image_Color,separator_color);
}
}
下來重點在於重寫基於ToolStripRenderer的類CustomProfessionalRenderer,在該類中,重載OnRenderToolStripBackground進行菜單背景條和菜單下拉項的重繪
protectedoverridevoid OnRenderToolStripBackground(ToolStripRenderEventArgs e)
{
//判斷ToolStrip的類型
ToolStrip tsType = e.ToolStrip;
Graphics g = e.Graphics;
//抗鋸齒
g.SmoothingMode = SmoothingMode.HighQuality;
if (tsType isMenuStrip ||
tsType isToolStripDropDown)
{
//指定填充Menu欄與ToolBar欄的背景色的畫刷,使用線性漸變畫刷
Rectangle rect = newRectangle(newPoint(0,0), newSize(tsType.Width-1,tsType.Height-1));
LinearGradientBrush lgBursh = newLinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
R0 = menu_color.R;
B0 = menu_color.B;
G0 = menu_color.G;
A0 = menu_color.A;
float[] pos = newfloat[4];
pos[0] = 0.0F;pos[1] = 0.3F; pos[2] = 0.35F; pos[3] = 1.0F;
Color[] colors = newColor[4];
colors[0] =GetColor(0, 35, 24, 9);
colors[1] =GetColor(0, 13, 8, 3);
colors[2] = Color.FromArgb(A0, R0, G0, B0);
colors[3] =GetColor(0, 28, 29, 14);
ColorBlend mix = newColorBlend();
mix.Colors = colors;
mix.Positions = pos;
lgBursh.InterpolationColors = mix;
//填充窗口區域
g.FillRectangle(lgBursh, rect);
if(tsType isMenuStrip)
{
rect = newRectangle(newPoint(1, 1), newSize(tsType.Width - 2, tsType.Height/3 -2));
SolidBrush sBrush = newSolidBrush(Color.FromArgb(100, 255, 255, 255));
g.FillRectangle(sBrush, rect);
sBrush.Dispose();
}
lgBursh.Dispose();
}
elseif (tsType isToolStrip)
{
//指定填充Menu欄與ToolBar欄的背景色的畫刷,使用線性漸變畫刷
LinearGradientBrush lgBursh = newLinearGradientBrush(newPoint(0, 0),
newPoint(0, tsType.Height),
Color.FromArgb(0, Color.White),
Color.FromArgb(150, Color.LightBlue));
GraphicsPath path = newGraphicsPath(FillMode.Winding);
int diameter = 10;//直徑
Rectangle rect = newRectangle(Point.Empty, tsType.Size);
Rectangle arcRect = newRectangle(rect.Location, newSize(diameter, diameter));
path.AddLine(0, 0,10, 0);
// 右上角
arcRect.X =rect.Right - diameter;
path.AddArc(arcRect,270, 90);
// 右下角
arcRect.Y =rect.Bottom - diameter;
path.AddArc(arcRect, 0, 90);
// 左下角
arcRect.X =rect.Left;
path.AddArc(arcRect,90, 90);
path.CloseFigure();
//設置控件的窗口區域
tsType.Region = newRegion(path);
//填充窗口區域
g.FillPath(lgBursh,path);
}
else
{
base.OnRenderToolStripBackground(e);
}
}
protectedoverridevoid OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
//判斷ToolStrip的類型
ToolStrip tsType = e.ToolStrip;
Graphics g = e.Graphics;
//抗鋸齒
g.SmoothingMode = SmoothingMode.HighQuality;
if (tsType isToolStripDropDown)
{
//設置畫筆
Pen LinePen = newPen(board_Color,0.5F);
Rectangle rect = newRectangle(newPoint(1, 1), newSize(tsType.Width - 3, tsType.Height -3));
//畫邊框
g.DrawRectangle(LinePen, rect);
}
elseif (tsType isToolStrip)
{
//設置畫筆
Pen LinePen = newPen(board_Color, 0.5F);
GraphicsPath path = newGraphicsPath();
Rectangle rect = newRectangle(newPoint(-1, -1), newSize(tsType.Width +1, tsType.Height -1));
path.AddRectangle(rect);
//畫邊框
g.DrawPath(LinePen,path);
}
else
{
base.OnRenderToolStripBorder(e);
}
}
重載OnRenderMenuItemBackground用於繪製菜單某項被鼠標選中時的狀態
protectedoverridevoid OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
{
Graphics g = e.Graphics;
ToolStripItem item = e.Item;
ToolStrip tsType = e.ToolStrip;
g.SmoothingMode = SmoothingMode.HighQuality;
//渲染頂級項
if (tsType isMenuStrip)
{
if (e.Item.Selected)
{
R0 =selected_Color.R;
B0 =selected_Color.B;
G0 =selected_Color.G;
A0 =selected_Color.A;
Rectangle rect = newRectangle(0, 0, item.Size.Width - 1,item.Size.Height - 1);
LinearGradientBrush lgBrush = newLinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
float[] pos = newfloat[4];
pos[0] = 0.0F;pos[1] = 0.3F; pos[2] = 0.35F; pos[3] = 1.0F;
Color[] colors = newColor[4];
colors[0] =GetColor(0, 0, 50, 100);
colors[1] =GetColor(0, 0, 0, 30);
colors[2] = Color.FromArgb(A0, R0, G0, B0);
colors[3] =GetColor(0, 0, 50, 100);
ColorBlend mix = newColorBlend();
mix.Colors =colors;
mix.Positions =pos;
lgBrush.InterpolationColors = mix;
g.FillRectangle(lgBrush, rect);
lgBrush.Dispose();
rect = newRectangle(newPoint(1, 1), newSize(tsType.Width - 2, tsType.Height / 3- 2));g.FillRectangle(newSolidBrush(Color.FromArgb(100, 255, 255, 255)),rect);
Pen LinesPen = newPen(board_Color);
Point[] LinePoint = { newPoint(0, 2),
newPoint(item.Size.Width - 1, 2),
newPoint(item.Size.Width - 1,item.Size.Height - 3),
newPoint(0, item.Size.Height - 3),
newPoint(0, 2)};
g.DrawLines(LinesPen, LinePoint);
LinesPen.Dispose();
}if (item.Pressed)
{
Pen LinesPen = newPen(board_Color,0.9F);//FromArgb(197, 228, 253));
Point[] LinePoint = { newPoint(0, 2),
newPoint(item.Size.Width - 1, 2),
newPoint(item.Size.Width - 1,item.Size.Height - 3),
newPoint(0, item.Size.Height - 3),
newPoint(0, 2)};
g.DrawLines(LinesPen, LinePoint);
LinesPen.Dispose();
}
}//渲染下拉項
elseif (tsType isToolStripDropDown)
{
g.SmoothingMode = SmoothingMode.HighQuality;
LinearGradientBrush lgbrush = newLinearGradientBrush(newPoint(0, 0), newPoint(item.Width, item.Height ), Color.FromArgb(250, selected_Color),Color.FromArgb(0, Color.White));
if (item.Selected)
{
GraphicsPath gp = GetRoundedRectPath(newRectangle(0, 0, item.Width, item.Height), 10);
// g.FillPath(lgbrush, gp);
R0 =selected_Color.R;
B0 =selected_Color.B;
G0 = selected_Color.G;
A0 =selected_Color.A;
Rectangle rect = newRectangle(0, 0, item.Size.Width - 1,item.Size.Height - 1);
LinearGradientBrush lgBrush = newLinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
float[] pos = newfloat[4];
pos[0] = 0.0F;pos[1] = 0.3F; pos[2] = 0.35F; pos[3] = 1.0F;
Color[] colors = newColor[4];
colors[0] =GetColor(0, 0, 50, 100);
colors[1] =GetColor(0, 0, 0, 30);
colors[2] = Color.FromArgb(A0, R0, G0, B0);
colors[3] =GetColor(0, 0, 50, 100);
ColorBlend mix = newColorBlend();
mix.Colors =colors;
mix.Positions =pos;
lgBrush.InterpolationColors = mix;
g.FillRectangle(lgBrush, rect);
lgBrush.Dispose();
rect = newRectangle(newPoint(1, 1), newSize(item.Size.Width - 2,item.Size.Height / 3 - 2));
g.FillRectangle(newSolidBrush(Color.FromArgb(100, 255, 255, 255)),rect);
Pen LinesPen = newPen(board_Color);
Point[] LinePoint = { newPoint(0, 2),
newPoint(item.Size.Width - 1, 2),
newPoint(item.Size.Width - 1,item.Size.Height - 3),
newPoint(0, item.Size.Height - 3),
newPoint(0, 2)};
g.DrawLines(LinesPen, LinePoint);
LinesPen.Dispose();
}
}
else
{
//base.OnRenderMenuItemBackground(e);
}
}
繼承OnRenderSeparator函數以便得到Separator的特定效果
protectedoverridevoid OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
{
Graphics g = e.Graphics;
ToolStrip tsType = e.ToolStrip;
if (tsType isToolStripDropDown)
{
LinearGradientBrush lgbrush = newLinearGradientBrush(newPoint(0, 0),
newPoint(e.Item.Width, 0),
separator_color,
Color.FromArgb(100,separator_color));
g.FillRectangle(lgbrush, newRectangle(25, e.Item.Height / 2, e.Item.Width / 8 * 7, 1));
}
}
重載OnRenderImageMargin繪製菜單項中右邊的顯示圖標的區域
protectedoverridevoid OnRenderButtonBackground(ToolStripItemRenderEventArgs e)
{
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
ToolStripItem item = e.Item;
if (item.Selected)
{
Pen LinesPen = newPen(Color.FromArgb(0, 0, 0));
Point[] LinePoint = { newPoint(0, 2),
newPoint(item.Size.Width - 1, 2),
newPoint(item.Size.Width - 1,item.Size.Height - 3),
newPoint(0, item.Size.Height - 3),
newPoint(0, 2)};
g.DrawLines(LinesPen, LinePoint);
SolidBrush brush = newSolidBrush(Color.FromArgb(197, 228, 253));
Rectangle rect = newRectangle(0, 2, item.Size.Width - 1,item.Size.Height - 5);
g.FillRectangle(brush, rect);
}
else
{
base.OnRenderMenuItemBackground(e);
}
}
至此,就完成了相應的菜單的繪製,得到效果:
具體代碼參見: https://download.csdn.net/download/mr_liyonghong/10308638