欢迎光临
我们一直在努力

用c#绘制Office2003样式的菜单-.NET教程,C#语言

建站超值云服务器,限时71元/月

我的方法是重写menuitem类,在写的过程中发现用gdi+实际测量出来的文本的大小不是很准确,还有文本也不能很好对齐,固在代码里可以时常看到很多多加上去的数字.我想原理就不用我讲了吧,下面的代码注释的很

清楚了:

using system;

using system.drawing;

using system.drawing.drawing2d;

using system.windows.forms;

namespace officemenu

{

/// <summary>

/// class1 的摘要说明。

/// </summary>

public class officemenuitem:menuitem

{

public officemenuitem(bool isapplyofficemenu,string itemtext)

{

if(isapplyofficemenu)

{

this.text=itemtext;

this.ownerdraw=true;

font=new font("宋体",9f,graphicsunit.point);

}

else

{

this.text=itemtext;

this.ownerdraw=false;

}

}

private font font;

private stringformat strformat=new stringformat();

private string itemtext="";

private string iconpath="";

//定义绘制的时候的各种笔刷

private lineargradientbrush topmenuhostlightbrush;

private solidbrush topmenudefaultbrush;

private solidbrush fontdefaultbrush;

private lineargradientbrush topmenuselectedbrush;

private solidbrush menudefaultbrush;

private solidbrush menudefaultselectedbrush;

private solidbrush menucheckbrush;

private lineargradientbrush menusidebarbrush;

private solidbrush menudefaultgrayedbrush;

//定义绘制的时候所需的各种线条

private pen topmenupen;

private pen menudefaultpen;

//定义需要的矩形结构

private rectangle sidebarrect;

private rectangle checkedrect;

private rectangle topmenurect;

private rectangle shortcutrect;

//定义图标

public string iconpath

{

get

{

return iconpath;

}

set

{

iconpath=value;

}

}

//判断菜单是否是顶级菜单

private bool checkistop()

{

if(typeof(mainmenu)==this.parent.gettype())

{

return true;

}

else

{

return false;

}

}

//获取菜单的快捷键

private string getshortcut()

{

string shortcut="";

try

{

if(this.showshortcut==true && (!this.isparent) && (!(this.shortcut==shortcut.none)))

{

shortcut=this.shortcut.tostring();

shortcut=shortcut.replace("ctrl","ctrl+");

shortcut=shortcut.replace("alt","alt+");

shortcut=shortcut.replace("shift","shift+");

}

}

catch

{

return "";

}

return shortcut;

}

//重写测量函数

protected override void onmeasureitem(measureitemeventargs e)

{

base.onmeasureitem (e);

try

{

itemtext=this.text;

sizef sizemenutext;

if(this.itemtext=="-") //设置分割线的高度

{

e.itemheight=5;

return;

}

string getedshortcut=this.getshortcut();

if(!this.checkistop()) //如果不是顶级菜单

{

sizemenutext=e.graphics.measurestring(itemtext+"".padright(4, )+getedshortcut,this.font);

e.itemwidth=convert.toint32(sizemenutext.width)+26;

}

else

{

sizemenutext=e.graphics.measurestring(itemtext,this.font);

e.itemwidth=convert.toint32(sizemenutext.width)-4;

}

if(this.visible)

{

e.itemheight=convert.toint32(sizemenutext.height)+6;

}

else

{

e.itemheight=0;

}

}

catch

{

e.itemheight=20;

e.itemwidth=80;

}

}

//重写绘图函数

protected override void ondrawitem(drawitemeventargs e)

{

if(this.visible)

{

base.ondrawitem (e);

rectangle menurect=e.bounds;

itemtext=this.text;

graphics g=e.graphics;

//绘制边框时需要的特殊矩形

sidebarrect=new rectangle(menurect.x,menurect.y,25,menurect.height);

//绘制选择框时需要的矩形

checkedrect=new rectangle(menurect.x+1,menurect.y+1,24,menurect.height-2);

//绘制顶菜单时需要的矩形

topmenurect=new rectangle(menurect.x+1,menurect.y+3,menurect.width,menurect.height);

//绘制shortcut用到的矩形

shortcutrect=new rectangle(menurect.x,menurect.y+4,menurect.width-10,menurect.height);

//定义绘制的时候的各种笔刷

topmenuhostlightbrush=new lineargradientbrush(menurect,color.white,color.fromargb(220,134,56),90f); //顶级菜单发生hotlight 时显示的颜色

topmenudefaultbrush=new solidbrush(systemcolors.control); //顶级菜单默认的颜色

fontdefaultbrush=new solidbrush(color.black); //字体默认的颜色

topmenuselectedbrush=new lineargradientbrush(menurect,color.white,color.fromargb(95,109,126),90f); //顶级菜单选中时的颜色

menudefaultbrush=new solidbrush(color.white); //默认菜单的颜色

menudefaultselectedbrush=new solidbrush(color.fromargb(247,218,157)); //菜单选中时的颜色

menucheckbrush=new solidbrush(color.fromargb(225,143,70)); //当菜单checked属性为真的时显示的颜色

menusidebarbrush=new lineargradientbrush(sidebarrect,color.white,color.fromargb(149,160,174),0f);//绘制侧栏

menudefaultgrayedbrush=new solidbrush(color.fromargb(105,105,105));//菜单不可用时

//定义绘制的时候所需的各种线条

topmenupen=new pen(brushes.black,1f); //顶级菜单的边框

menudefaultpen=new pen(new solidbrush(color.fromargb(60,60,115)),1f); //正常选择时的边框

//开始绘制****************************************************

if(this.checkistop() && this.itemtext!="-") //如果是顶级菜单

{

bool isdraw=false;//定义一个变量保证正常显示的只绘制一次 避免浪费资源

strformat.alignment=stringalignment.center;

if(isdraw==false) //绘制正常显示时的图像

{

g.fillrectangle(topmenudefaultbrush,menurect);

g.drawstring(itemtext,this.font,fontdefaultbrush,topmenurect,strformat);

}

//绘制hotlight时的图像

if((e.state & drawitemstate.hotlight)==drawitemstate.hotlight) //突出显示时

{

g.fillrectangle(topmenuhostlightbrush,menurect);

g.drawrectangle(topmenupen,menurect.x,menurect.y,menurect.width-1,menurect.height-1);

g.drawstring(itemtext,this.font,fontdefaultbrush,topmenurect,strformat);

isdraw=true;

}

//绘制菜单选中时的图像

if((e.state & drawitemstate.selected)==drawitemstate.selected)

{

g.fillrectangle(topmenuselectedbrush,menurect);

g.drawrectangle(topmenupen,menurect.x,menurect.y,menurect.width-1,menurect.height-1);

g.drawstring(itemtext,this.font,fontdefaultbrush,topmenurect,strformat);

isdraw=true;

}

}

else //非顶级菜单时

{

if(this.itemtext!="-")

{

bool isdraw=false;

if(isdraw==false) //正常显示时

{

g.fillrectangle(menudefaultbrush,menurect);

g.fillrectangle(menusidebarbrush,menurect.x,menurect.y,25,menurect.height);

g.drawstring(itemtext,this.font,fontdefaultbrush,menurect.x+26,menurect.y+4);

//绘制shortcut

string shortcut=this.getshortcut();

strformat.alignment=stringalignment.far;

g.drawstring(shortcut,this.font,fontdefaultbrush,shortcutrect,strformat);

//绘制图标

this.drawicon(g);

}

if((e.state & drawitemstate.selected)==drawitemstate.selected) //选中时

{

this.drawitem_selected(g,menurect,itemtext);

isdraw=true;

}

if((e.state & drawitemstate.grayed)==drawitemstate.grayed) //不可用时

{

g.drawstring(itemtext,this.font,menudefaultgrayedbrush,menurect.x+26,menurect.y+4);

isdraw=true;

}

if(!this.isparent)

{

if((e.state & drawitemstate.checked)==drawitemstate.checked) //选择时

{

g.fillrectangle(menucheckbrush,checkedrect);

g.drawrectangle(new pen(brushes.black,1f),menurect.x+1,menurect.y+1,23,menurect.height-3);

g.drawstring("√",this.font,fontdefaultbrush,menurect.x+3,menurect.y+4);

isdraw=true;

}

if(this.checked==true && ((e.state & drawitemstate.selected)==drawitemstate.selected)) //选中且checked属性为真时

{

g.fillrectangle(new solidbrush(color.fromargb(255,91,91)),checkedrect);

g.drawrectangle(new pen(brushes.black,1f),menurect.x+1,menurect.y+1,23,menurect.height-3);

g.drawstring("√",this.font,fontdefaultbrush,menurect.x+3,menurect.y+4);

isdraw=true;

}

}

}

else //画分割线

{

solidbrush partitionlinebrush=new solidbrush(color.fromargb(128,128,128));

pen partitionpen=new pen(partitionlinebrush,1f);

g.fillrectangle(menudefaultbrush,menurect);

g.fillrectangle(menusidebarbrush,menurect.x,menurect.y,25,menurect.height);

g.drawline(partitionpen,new point(menurect.x+27,menurect.y+2),new point(menurect.x+27+(menurect.width-26),menurect.y+2));

}

}

}

}

//画图标

private void drawicon(graphics g)

{

if(this.checkistop()==false && this.iconpath!="" && this.isparent==false && this.checked==false)

{

try

{

bitmap iconimage=new bitmap(this.iconpath);

int imagewidth=iconimage.width;

int imageheight=iconimage.height;

if(imagewidth<=checkedrect.width && imageheight<=checkedrect.height)

{

int imagerecwidthmistake=checkedrect.width-imagewidth;

float mistake_2=(float)imagerecwidthmistake/2f;

g.drawimage(iconimage,checkedrect.x+(int)mistake_2,checkedrect.y,imagewidth,imageheight);

}

else

{

g.drawimage(iconimage,checkedrect);

}

}

catch

{

throw new iconnotfindexception("不能创建图标,可能是路径不能也可能是不支持此格式");

}

}

}

//由于再绘制的过程中选中的动作时需要执行两次一样的代码 固在这里用了一个函数

private void drawitem_selected(graphics g,rectangle rec,string itemtext)

{

solidbrush tmpbrush;

if(this.enabled)

{

tmpbrush=fontdefaultbrush;

}

else

{

tmpbrush=menudefaultgrayedbrush;

}

//正常显示

g.fillrectangle(menudefaultselectedbrush,rec);

g.drawrectangle(menudefaultpen,rec.x,rec.y,rec.width-1,rec.height-1);

g.drawstring(itemtext,this.font,tmpbrush,rec.x+26,rec.y+4);

//显示shortcut

string shortcut=this.getshortcut();

strformat.alignment=stringalignment.far;

g.drawstring(shortcut,this.font,tmpbrush,shortcutrect,strformat);

//画图标

this.drawicon(g);

}

}

//自定义异常

public class iconnotfindexception:applicationexception

{

public iconnotfindexception(string message)

:base(message)

{

}

}

}

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 用c#绘制Office2003样式的菜单-.NET教程,C#语言
分享到: 更多 (0)