人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當(dāng)前位置:蘿卜系統(tǒng)下載站 > 技術(shù)開(kāi)發(fā)教程 > 詳細(xì)頁(yè)面

用C#與VB.NET完成VS.NET或Office XP風(fēng)格的菜單(3)

用C#與VB.NET完成VS.NET或Office XP風(fēng)格的菜單(3)

更新時(shí)間:2022-06-25 文章作者:未知 信息來(lái)源:網(wǎng)絡(luò) 閱讀次數(shù):

用C#和VB.NET實(shí)現(xiàn)VS.NET或Office XP風(fēng)格的菜單

小氣的神 2001.08.18

3. “MenuItemStyle”接口和VS.NET風(fēng)格的菜單項(xiàng)



這個(gè)Project又將切換到C#語(yǔ)言。我是這樣想的:先針對(duì)普通菜單、Office200風(fēng)格、VS.NET風(fēng)格三種情況定義一個(gè)統(tǒng)一的接口(interface),其中包括畫Icon(DrawIcon)、畫分割條(DrawSeparator)、畫菜單背景(DrawBackground)、寫菜單項(xiàng)的文字(DrawMenuText)等功能;普通、Office2000和VS.NET根據(jù)各自不同的情況實(shí)現(xiàn)這個(gè)接口的Drawxxx的功能。然后從MenuItem繼承一個(gè)子類,象第二部分講的那樣Overrides 菜單項(xiàng)的兩個(gè)函數(shù):OnMeasureItem和OnDrawItem,根據(jù)不同的風(fēng)格調(diào)用上面實(shí)現(xiàn)的接口中的DrawXXX函數(shù)就可以了。最后我把這部分都分隔出來(lái)放在一個(gè).CS文件中,單獨(dú)編譯成一個(gè)VSNET.Menu.DLL,你只用using VSNET.Menu ; 然后就可以象在第一部分那樣象使用普通的MenuItem那樣來(lái)用了,Demo源代碼中你還可以看到我定義了IconMenuItem的類,它有一個(gè)方法:MenuItemCreator(VSNET.Menu.IconMenuStyle sType , String sText , Bitmap bmp , System.EventHandler eh)可以完成生成需要的MenuItem。本來(lái)我想用資源文件或?qū)D片Icon等資源放在一個(gè)專門的文件中,然后由這個(gè)類來(lái)負(fù)責(zé)從資源文件或外部的類中獲得資源CreateMenuItem。但是是第一版,你會(huì)看到例程中我仍然用原始的New Bitmap()的方式直接從硬盤拿資源。當(dāng)我看到它show出來(lái)時(shí),先是很開(kāi)心,然后發(fā)現(xiàn)還有許多要改進(jìn),想想其實(shí)做一個(gè)專業(yè)的菜單也需要花許多心思。

好吧讓我們看一下有關(guān)VS.NET風(fēng)格菜單項(xiàng)這部分主要的實(shí)現(xiàn)代碼:



public class VSNetStyle : MenuItemStyleDrawer

{

static Color bgcolor = Color.FromArgb(246, 246, 246);

static Color ibgcolor = Color.FromArgb(202, 202, 202);

static Color sbcolor = Color.FromArgb(173, 173, 209);

static Color sbbcolor = Color.FromArgb( 0, 0, 128);



static int TEXTSTART = 20;



public void DrawCheckmark(Graphics g, Rectangle bounds, bool selected)

{

ControlPaint.DrawMenuGlyph(g, new Rectangle(bounds.X + 2, bounds.Y + 2, 14, 14), MenuGlyph.Checkmark);

}



public void DrawIcon(Graphics g, Image icon, Rectangle bounds, bool selected, bool enabled, bool ischecked)

{

if (enabled)

{

if (selected)

{

ControlPaint.DrawImageDisabled(g, icon, bounds.Left + 2, bounds.Top + 2, Color.Black);

g.DrawImage(icon, bounds.Left + 1, bounds.Top + 1);

}

else

{

g.DrawImage(icon, bounds.Left + 2, bounds.Top + 2);

}

}

else

ControlPaint.DrawImageDisabled(g, icon, bounds.Left + 2, bounds.Top + 2, SystemColors.HighlightText);

}



public void DrawSeparator(Graphics g, Rectangle bounds)

{

int y = bounds.Y + bounds.Height / 2;

g.DrawLine(new Pen(SystemColors.ControlDark), bounds.X + SystemInformation.SmallIconSize.Width + 7, y, bounds.X + bounds.Width - 2, y);

}



public void DrawBackground(Graphics g, Rectangle bounds, DrawItemState state, bool toplevel, bool hasicon)

{

bool selected = (state & DrawItemState.Selected) > 0;



if (selected || ((state & DrawItemState.HotLight) > 0))

{

if (toplevel && selected)

{ // draw toplevel, selected menuitem

g.FillRectangle(new SolidBrush(ibgcolor), bounds);

ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, bounds.Width, bounds.Height, Border3DStyle.Flat, Border3DSide.Top | Border3DSide.Left | Border3DSide.Right);

}

else

{ // draw menuitem, selected OR toplevel, hotlighted

g.FillRectangle(new SolidBrush(sbcolor), bounds);

g.DrawRectangle(new Pen(sbbcolor), bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);

}

}

else

{

if (!toplevel)

{ // draw menuitem, unselected

g.FillRectangle(new SolidBrush(ibgcolor), bounds);

bounds.X += SystemInformation.SmallIconSize.Width + 5;

bounds.Width -= SystemInformation.SmallIconSize.Width + 5;

g.FillRectangle(new SolidBrush(bgcolor), bounds);

}

else

{

// draw toplevel, unselected menuitem

g.FillRectangle(SystemBrushes.Menu, bounds);

}

}

}



public void DrawMenuText(Graphics g, Rectangle bounds, string text, string shortcut, bool enabled, bool toplevel, DrawItemState state)

{

StringFormat stringformat = new StringFormat();

stringformat.HotkeyPrefix = ((state & DrawItemState.NoAccelerator) > 0) ? HotkeyPrefix.Hide : HotkeyPrefix.Show;

int textwidth = (int)(g.MeasureString(text, SystemInformation.MenuFont).Width);



int x = toplevel ? bounds.Left + (bounds.Width - textwidth) / 2: bounds.Left + TEXTSTART;

int y = bounds.Top + 2;

Brush brush = null;

if (!enabled)

brush = new SolidBrush(Color.FromArgb(120, SystemColors.MenuText));

else

brush = new SolidBrush(Color.Black);

g.DrawString(text, SystemInformation.MenuFont, brush, x, y, stringformat);

g.DrawString(shortcut, SystemInformation.MenuFont, brush, bounds.Left + 130, bounds.Top + 2, stringformat);

}

}



MenuItemStyleDrawer就是那個(gè)公用的接口類,無(wú)論普通風(fēng)格、Office2000還是VS.NET風(fēng)格都要實(shí)現(xiàn)自己方式的接口,這個(gè)接口包括DrawCheckmark、DrawIcon、DrawMenuText、DrawBackground、DrawSeparator等函數(shù),可以實(shí)現(xiàn)菜單項(xiàng)需要的各種函數(shù)。完成這部分后可以從MenuItem繼承一個(gè)子類來(lái)象第二部分一樣處理了。看下面的代碼,具體考察一下熟悉的OnMeasureItem和OnDrawItem:

protected override void OnMeasureItem(MeasureItemEventArgs e)

{

base.OnMeasureItem(e);



// make shortcut text 省略這部分代碼。

if (menustyle != IconMenuStyle.Standard)

{

if (Text == "-")

{

e.ItemHeight = 8;

e.ItemWidth = 4;

return;

}

int textwidth = (int)(e.Graphics.MeasureString(Text + shortcuttext, SystemInformation.MenuFont).Width);

e.ItemHeight = SystemInformation.MenuHeight;

if (Parent == Parent.GetMainMenu())

e.ItemWidth = textwidth - 5; // 5 is a magic number

else

e.ItemWidth = Math.Max(160, textwidth + 50);

}

}



IconMenuStyle.Standard是個(gè)enum表明是普通風(fēng)格、Office2000或是VS。NET的風(fēng)格。這部分和我們第二部分看到的沒(méi)有什么不同。

protected override void OnDrawItem(DrawItemEventArgs e)

{

base.OnDrawItem(e);

Graphics g = e.Graphics;

Rectangle bounds = e.Bounds;

bool selected = (e.State & DrawItemState.Selected) > 0;

bool toplevel = (Parent == Parent.GetMainMenu());

bool hasicon = Icon != null;



style.DrawBackground(g, bounds, e.State, toplevel, hasicon);

if (hasicon)

style.DrawIcon(g, Icon, bounds, selected, Enabled, Checked);

else

if (Checked)

style.DrawCheckmark(g, bounds, selected);



if (Text == "-")

{

style.DrawSeparator(g, bounds);

}

else

{

style.DrawMenuText(g, bounds, Text, shortcuttext, Enabled, toplevel, e.State);

}

}



剛剛我們說(shuō)的MenuItemStyleDrawer接口的好處在這里顯示出來(lái),整個(gè)過(guò)程顯得簡(jiǎn)單明了,具體實(shí)現(xiàn)得代碼不是很多。當(dāng)這個(gè)類完成后,剩下來(lái)的就是使用了它了,這部分象第一部分所述,你可以在一個(gè)頂級(jí)菜單項(xiàng)的子菜單項(xiàng)聲明成IconMenu類型的也就是我們實(shí)現(xiàn)的繼承MenuItem的類,簡(jiǎn)單的代碼象下面這樣:

private System.Windows.Forms.MenuItem mItems1 ; System.Drawing.Bitmap Bitmap1 = new Bitmap( BMPPATHSTR + "Open.bmp") ;



mItems1 = iMenuItem.MenuItemCreator( MenuStyle , "&Open" , Bitmap1,

這個(gè)mItem1就是一個(gè)VS.NET風(fēng)格的菜單項(xiàng)了。具體的可以看附帶的Project和屏幕截圖。



至此我們完成了用VB.NET或C#完成一個(gè)有VS.NET或Office XP風(fēng)格的菜單。三個(gè)部分是漸進(jìn)的,如果你以前進(jìn)行或?qū)嶒?yàn)過(guò)第二部分討論的問(wèn)題,那么第三部分唯一讓人感興趣的是MenuItemStyleDrawer接口的思路。對(duì)于整個(gè)新的.NET的編程方式上說(shuō),原來(lái)的VB用戶可能會(huì)經(jīng)歷一個(gè)痛苦的過(guò)程,他們的第一反應(yīng)是Sub Class、Hook或是終極的API,而接觸過(guò)C++、MFC、DELPHI甚至VJ++的用戶會(huì)很容易想到繼承,特別時(shí)DELPHI和VJ的用戶入手應(yīng)當(dāng)最快了。想想會(huì)開(kāi)始懷念以前VB的時(shí)光,因?yàn)閷?duì)于這樣的問(wèn)題,VB用戶總是拿著大錘,直接敲個(gè)大洞,然后拿到結(jié)果;而C++、MFC、DEPHI用戶則拿著一本說(shuō)明書,一步一步按指示找到結(jié)果;結(jié)果可能一樣,但兩者的方式是截然不同的。好了,這些是

溫馨提示:喜歡本站的話,請(qǐng)收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
主站蜘蛛池模板: 西林县| 和政县| 调兵山市| 凤山县| 文昌市| 来安县| 黑龙江省| 遂昌县| 洞头县| 郓城县| 鄱阳县| 左贡县| 化州市| 石家庄市| 米易县| 许昌市| 周至县| 上虞市| 怀远县| 遂川县| 石屏县| 广平县| 长垣县| 宜城市| 兴业县| 通城县| 寿宁县| 哈尔滨市| 大竹县| 南溪县| 得荣县| 平度市| 澄迈县| 永丰县| 库尔勒市| 巴塘县| 资溪县| 怀来县| 越西县| 茂名市| 云安县|