分享
 
 
 

Owner Draw Menus in C#

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

很多Windows 应用程序中的控件可以手工绘制,来达到更加生动的效果,可以使用窗体组件的ownerdraw属性来达到这个目的。Menu就是一个这样的组件,它允许我们手工绘制其界面。

这篇文章的主要目的在于向你解释如何用特定的字体,图片,背景颜色以及其他的图形对象来绘制自己定制的菜单。

第一步:创建一个简单的Windows Form应用程序

点击文件 - > 新建 -> 项目 - > 创建一个新的C#WindowsForm应用程序:OwnerDrawMenu

在默认的窗体上,添加一个“MainMenu”控件, 创建如下形式的菜单

在这里我们需要手工绘制的菜单不仅仅是顶级菜单,而且包括子菜单

对每个菜单项,设置其OwnerDraw属性为“True”

对每个菜单项而言,手工绘制将调用如下两个函数..

DrawItem . 这个函数里将加入实际的绘图逻辑.

Measure Item . 这个函数被调用于设置菜单项的高度和宽度值.

在菜单项的事件列表里,我们将为其添加这两个事件函数.

选择“File”菜单的属性页.

点击“Event”标签页.

双击“DrawItem”选项.这将为“File”菜单添加一个默认的绘制事件处理函数.

private void mi_TopMenuItem_DrawItem(

object sender, System.Windows.Forms.DrawItemEventArgs e)

双击“MeasureItem”选项。这将为“File”菜单添加一个默认的测量事件处理函数

private void mi_TopMenuItem_MeasureItem(

object sender, System.Windows.Forms.MeasureItemEventArgs e)

现在我们需要为子菜单添加DrawItem 和 MeasureItem 事件处理函数. 对所有子菜单,我们创建不同的事件函数

选中“Open”子菜单,同样的添加两个事件处理函数

private void mi_SubMenuItem_MeasureItem(

object sender, System.Windows.Forms.MeasureItemEventArgs e)

private void mi_SubMenuItem_DrawItem(

object sender, System.Windows.Forms.DrawItemEventArgs e)

注意:这里我们并不是对每个菜单项都创建一个相应的事件处理函数,尽管你可以这样做。相反的,我们通过一个通用的事件处理函数(mi_TopMenuItem_DrawItem)来处理所有顶级菜单项(File/Options/Help)的DrawItem事件,一个通用的事件处理函数来处理所有顶级菜单项的MeasureItem事件;一个通用的事件处理函数(mi_SubMenuItem_DrawItem)来处理所有的子菜单项(Open/Close…About)的DrawItem事件,一个通用的事件处理函数(mi_SubMenuItem_MeasureItem)来处理所有的子菜单的MeasureItem事件。

下面是详细步骤..

对其他的两个顶级菜单项“Options”、“Help”,在窗体设计器中选中它,选其属性页,选到事件页.

点击DrawItem 事件右边的下拉列表,选中mi_TopMenuItem_DrawItem.

点击MeasureItem 事件右边的下拉列表,选中mi_TopMenuItem_ MeasureItem.

对于每个子菜单,例如“Close / Exit / Security / Network / About”,选其属性页,选到事件页.

点击DrawItem 事件右边的下拉列表,选中mi_SubMenuItem_DrawItem.

点击MeasureItem 事件右边的下拉列表,选中mi_SubMenuItem_ MeasureItem.

现在对于每个菜单项我们都为其添加了DrawItem 和 MeasureItem的事件处理函数.

下面是顶级菜单的事件处理函数

private void mi_TopMenuItem_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)

{

Brush sysBgBrush = new SolidBrush(SystemColors.Control);

Brush focuseBgBrush = new SolidBrush(Color.CornflowerBlue);

Font normalFont = new Font("Ariel", 10);

Brush normalTxBrush = new SolidBrush(Color.Black);

Pen bdrPen1 = new Pen(normalTxBrush, 2);

Pen bdrPen2 = new Pen(normalTxBrush);

Rectangle rc = new Rectangle(e.Bounds.X+1 , e.Bounds.Y+1, e.Bounds.Width-5, e.Bounds.Height-1);

e.Graphics.FillRectangle(sysBgBrush , rc);

MenuItem mOrigin = (MenuItem)sender ;

string mItemText = mOrigin.Text ;

StringFormat sf = new StringFormat();

sf.Alignment = StringAlignment.Center ;

e.Graphics.DrawString(mItemText , normalFont, normalTxBrush , rc , sf );

//Console.WriteLine(e.State.ToString());

if ( e.State == (DrawItemState.NoAccelerator | DrawItemState.Selected)

|| e.State == ( DrawItemState.NoAccelerator | DrawItemState.HotLight) )

{

e.Graphics.FillRectangle( focuseBgBrush, rc);

e.Graphics.DrawString( mItemText , normalFont ,normalTxBrush, rc ,sf);

e.Graphics.DrawRectangle(bdrPen2, rc );

}

e.DrawFocusRectangle();

e.Graphics.DrawRectangle(bdrPen1, rc );

}

private void mi_TopMenuItem_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)

{

e.ItemHeight = 25;

e.ItemWidth = 75;

}

下面是子菜单的事件处理函数

private void mi_SubMenuItem_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)

{

Rectangle rc = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);

Brush sysBgBrush = new SolidBrush(SystemColors.Control);

Brush focuseBrush = new SolidBrush(Color.CornflowerBlue);

Font normalFont = new Font("Veranda", 10);

Brush normalTxBrush = new SolidBrush(Color.Blue);

Font focuseFont = new Font("Veranda", 10, FontStyle.Bold|FontStyle.Underline);

Brush focuseTxBrush = new SolidBrush(Color.Yellow);

Pen sysBdPen = new Pen(sysBgBrush);

Pen focuseBdPen = new Pen(new SolidBrush(Color.Black));

//erase the previous track

e.Graphics.FillRectangle(sysBgBrush , rc);

MenuItem mOrigin = (MenuItem)sender ;

string mItemText = mOrigin.Text ;

StringFormat textFormat = new StringFormat();

textFormat.Alignment = StringAlignment.Far ;

textFormat.LineAlignment = StringAlignment.Center;

Rectangle rcText = rc ;

rcText.Width-=5 ;

e.Graphics.DrawString(mItemText , normalFont, normalTxBrush, rcText, textFormat );

e.Graphics.DrawRectangle(sysBdPen, rc );

if ( e.State == ( DrawItemState.NoAccelerator | DrawItemState.Selected))

{

e.Graphics.FillRectangle(focuseBrush , rc);

e.Graphics.DrawString( mItemText , focuseFont , focuseTxBrush, rcText,textFormat);

e.Graphics.DrawRectangle(focuseBdPen, rc );

e.DrawFocusRectangle();

}

Image useImage = null ;

if ( mOrigin == mi_File_New )

{

useImage = this.imageList1.Images[0];

}

if ( mOrigin == mi_File_Open )

{

useImage = this.imageList1.Images[1];

}

if ( mOrigin == mi_File_Save )

{

useImage = this.imageList1.Images[2];

}

if ( useImage != null )

{

SizeF sz = useImage.PhysicalDimension;

e.Graphics.DrawImage(useImage, e.Bounds.X+5,

( e.Bounds.Bottom + e.Bounds.Top ) /2 - sz.Height/2);

}

}

private void mi_SubMenuItem_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)

{

e.ItemHeight = 25;

e.ItemWidth = 75;

}

编译并执行.

About the Author Shripad Kulkarni

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有