首页 > 开发 > .Net > 正文

用C#和VB.NET实现VS.NET或Office XP风格的菜单(二)

2020-02-03 15:30:44
字体:
来源:转载
供稿:网友
用c#和vb.net实现vs.net或office xp风格的菜单

小气的神 2001.08.18

2.“owner-drawn menus”技术

这个例子是vb.net语法的.我去掉了和menu无关的class,原因是错误太多,你会遇到类库和命名空间的移植性的问题:

最多的是beta1 system.winforms 和beta 2 的system.windows.froms的命名空间问题;

然后是beta1中的bitand 、bitor等等bitxxx的函数在beta2中已去掉了bit又和vb中一样了(据说beta1的这项改动遭到了总多vb fans的投诉,说不能把vb也c#化,bit是什么东东),这样你需要把这类函数改掉;

然后是nameobjectcollectionbase从原来的system.collections中删除了,beta2放在system.collections.specialized 中,真的有些昏倒,开始我还以为beta2中删除了这个类。

最后是一些overrides和 overloads的问题,具体的看vs.net或framework sdk beta 2编译时的提示就可以了,这方面ms做得不错,task list中告诉你具体得建议,照做就是了。

具体一点你可以在framework sdk beta 2安装目录的doc目录中找到这两个文件,这是从beta1移植到beta2上不错的指导文件:apichangesbeta1tobeta2.htm 和change list - beta1 to beta2.doc 特别是这个doc文件洋洋洒洒90多页,但很有帮助。

希望你还能在排除所有的错误之后保持清醒,找到最核心有用的代码,来分析。主要是cactionmenu.vb,焦点在onmeasureitem和ondrawitem这两个函数或说事件处理程序上。onmeasureitem主要是处理menuitem的itemheight和itemwidth的,从它传的measureitemeventargs参数数就知道。ondrawitem主要是如何画菜单的问题。关键字overrides表明我们要在子类中重新定义menuitem中的这两个方法。



从56行到58行是onmeasureitem函数:

protected overrides sub onmeasureitem(byval e as system.windows.forms.measureitemeventargs)

if me.action.caption = "-" then

e.itemheight = 5

else

e.itemheight = 20

end if

dim fs as fontstyle

if me.defaultitem = true then fs = fs or fontstyle.bold

dim fnt as new font("tahoma", 8, fs)

dim sf as sizef = e.graphics.measurestring(me.action.caption, fnt)

fnt.dispose()

e.itemwidth = cint(sf.width) + 20

end sub

measureitemeventargs提供4个属性graphis、index、itemheight和itemwidth。me相当于c#或java的this关键字。fnt.dispose()中dispose是一个很有意思的函数调用,在以往的windows编程中象字体、画笔等许多资源都希望快使用快释放,这个语句是用来控制gc(garbage collection)的,意思是我已使用完了这个设备或资源,gc你可以收回了。



从70到146行是有关onitemdraw函数的:

protected overrides sub ondrawitem(byval e as system.windows.forms.drawitemeventargs)

' colors, fonts

dim clrbgicon, clrbgtext, clrtext as color, fs as fontstyle, fnt as font

dim b as solidbrush, p as pen

dim fenabled as boolean = not ctype(e.state and drawitemstate.disabled, boolean)

dim fselected as boolean = ctype(e.state and drawitemstate.selected, boolean)

dim fdefault as boolean = ctype(e.state and drawitemstate.default, boolean)

dim fbreak as boolean = (me.action.caption = "-")

if fenabled and fselected and not fbreak then

clrbgicon = color.silver

clrbgtext = color.white

clrtext = color.blue

fs = fs or fontstyle.underline

else

clrbgicon = color.gray

clrbgtext = color.silver

clrtext = color.black

end if

if not fenabled then

clrtext = color.white

end if

if fdefault then

fs = fs or fontstyle.bold

end if

fnt = new font("tahoma", 8, fs)

' total background (partly to remain for icon)

b = new solidbrush(clrbgicon)

e.graphics.fillregion(b, new [region](e.bounds))

b.dispose()

' icon?

if not me.action.actionlist is nothing then

dim il as imagelist = me.action.actionlist.imagelist

if not il is nothing then

dim index as integer = me.action.image

if index > -1 and index < il.images.count then

dim rect as rectangle = e.bounds

with rect

.x += 2

.y += 2

.width = 16

.height = 16

end with

e.graphics.drawimage(il.images.item(index), rect)

end if

end if

end if

' text background

dim rf as rectanglef

with rf

.x = 18

.y = e.bounds.y

.width = e.bounds.width - .x

.height = e.bounds.height

end with

b = new solidbrush(clrbgtext)

e.graphics.fillregion(b, new [region](rf))

b.dispose()

' text/line

rf.y += 3 : rf.height -= 3

if not fbreak then

b = new solidbrush(clrtext)

e.graphics.drawstring(me.action.caption, fnt, b, rf)

fnt.dispose()

b.dispose()

else

p = new pen(color.black)

rf.y -= 1

e.graphics.drawline(p, rf.x, rf.y, rf.right, rf.y)

p.dispose()

end if

' border

if fenabled and fselected and not fbreak then

p = new pen(color.black)

e.graphics.drawrectangle(p, e.bounds)

p.dispose()

end if

end sub



drawitemeventargs参数给了你和菜单相关的所有环境和信息,它包括6个属性:bounds、font、forecolor、graphics、index、states。如果你以前用过windows下的gdi函数,那一定很熟悉这些函数,不是很复杂只需要你一点点算术知识和美术观点就可以了,如果你是第一次那么在纸上画几个矩形块就可以了理解和做的很好,比起以前tc下的菜单编程容易得多。主要是作者是如何把icon画在菜单上的,然后是根据不同的states表现一下菜单的forecolor, bounds就是菜单项最前面的表示选中等等的小方块。

好了第二部分涉及到了大部分技术细节了,这里你需要关注的是,如何画出来,下一部分我们来看如何画的好看些,象vs.net或office xp那样子。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表