. NET 技术讨论

学于明志,交流增加见识,讨论改变思维
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

winForm下菜单制作(类似VS.NET的工具拦上的菜单样式)

Posted on 2006-05-12 10:50    阅读(1119)  评论(0编辑  收藏  举报

很多工具软件界面都很漂亮,尤其是右键弹出菜单也非常的漂亮

然而VS.NET自带的MenuItem类库做出来的右键弹出菜单功能虽然实现
但是样式却很普通,下面这个cs文件重写了MenuItem类,样子将变的很漂亮
基本上可以满足任何要求,用户也可以根据自己需要做稍微的修改;用的时候

只要NEW一个这个对象即可,以下是具体代码:

  1 using System;
  2 using System.Windows;
  3 using System.Drawing;
  4 using System.Drawing.Drawing2D;
  5 using System.Windows.Forms;
  6 using System.ComponentModel;
  7 using System.Drawing.Text;
  8 using System.Diagnostics;
  9 using System.Collections;
 10 
 11 namespace DocCenter
 12 {
 13     /// <summary>
 14     /// 自绘菜单
 15     /// </summary>
 16     public class OwnerDrawMenu : MenuItem 
 17     {
 18         private static Color backcolor;
 19         private static Color barcolor;
 20         private static Color selectioncolor;
 21         private static Color framecolor;    
 22         private static int iconSize = SystemInformation.SmallIconSize.Width + 5;        
 23         private static int itemHeight;
 24         private string shortcuttext = "";
 25         private Image icon   = null;
 26         private static int BITMAP_SIZE = 16;
 27         private static int STRIPE_WIDTH = iconSize + 5;
 28 
 29         public OwnerDrawMenu() : base() 
 30         {
 31             OwnerDraw = true
 32         }
 33         
 34         private OwnerDrawMenu(string name) : base(name) 
 35         {
 36             OwnerDraw = true
 37         }
 38 
 39         public OwnerDrawMenu(string name, EventHandler handler) : base(name, handler) 
 40         {
 41             OwnerDraw = true
 42         }
 43 
 44         private OwnerDrawMenu(string name, EventHandler handler, Shortcut shortcut) : base(name, handler, shortcut) 
 45         {
 46             OwnerDraw = true;
 47         }
 48 
 49         private OwnerDrawMenu(MenuMerge mergeType, int mergeOrder, Shortcut shortcut, string name, EventHandler onClick, EventHandler onPopup, EventHandler onSelect, OwnerDrawMenu[] items) : base(mergeType, mergeOrder, shortcut, name, onClick, onPopup, onSelect, items) 
 50         {
 51             OwnerDraw = true;
 52         }
 53 
 54         private OwnerDrawMenu(string name, Image img) : this(name) 
 55         {
 56             OwnerDraw = true;
 57             icon = img;
 58         }
 59 
 60         private OwnerDrawMenu(string name, EventHandler handler, Image img) : this(name, handler) 
 61         {
 62             OwnerDraw = true;
 63             icon = img;
 64         }
 65         
 66         private OwnerDrawMenu(string name, EventHandler handler, Shortcut shortcut, Image img) : this(name, handler, shortcut) 
 67         {
 68             OwnerDraw = true;
 69             icon = img;
 70         }
 71 
 72         public Image Icon 
 73         {
 74             get
 75             {
 76                 return icon;
 77             }
 78             set
 79             {
 80                 icon = value;
 81             }
 82         }
 83 
 84         private string ShortcutText 
 85         {
 86             get 
 87             { return shortcuttext; }
 88             set 
 89             { shortcuttext = value;    }
 90         }
 91 
 92         public Color SelectionColor
 93         {
 94             get
 95             { return selectioncolor; }
 96             set
 97             { selectioncolor = value; }
 98         }
 99 
100         public Color BackColor
101         {
102             get
103             { return backcolor; }
104             set
105             { backcolor = value; }
106         }
107 
108         public Color BarColor
109         {
110             get
111             { return barcolor; }
112             set
113             { barcolor = value; }
114         }
115 
116         public Color FrameColor
117         {
118             get
119             { return framecolor; }
120             set
121             { framecolor = value; }
122             
123         }
124               
125         protected override void OnMeasureItem(MeasureItemEventArgs e) 
126         { 
127             if (Shortcut != Shortcut.None) 
128             {   
129                 string text = "";
130                 int    key  = (int)Shortcut;
131                 int    ch   = key & 0xFF;
132                 if (((int)Keys.Control & key) > 0) text += "Ctrl+";
133                 if (((int)Keys.Shift & key) > 0) text += "Shift+";
134                 if (((int)Keys.Alt & key) > 0) text += "Alt+";
135                 if (ch >= (int)Shortcut.F1 && ch <= (int)Shortcut.F12)
136                     text += "F" + (ch - (int)Shortcut.F1 + 1);
137                 else 
138                 {
139                     if ( Shortcut == Shortcut.Del) 
140                     {
141                         text += "Del";
142                     }
143                     else 
144                     {
145                         text += (char)ch;
146                     }
147                 }
148                 shortcuttext = text;
149             } 
150             if (Text == "-"
151             {
152                 e.ItemHeight = 8;
153                 e.ItemWidth  = 4;
154                 return;
155             }
156             bool topLevel = Parent == Parent.GetMainMenu();
157             string tempShortcutText = shortcuttext;
158             if ( topLevel ) 
159             {
160                 tempShortcutText = "";
161             }
162             int textwidth = (int)(e.Graphics.MeasureString(Text + tempShortcutText, SystemInformation.MenuFont).Width);
163             int extraHeight = 4;
164             e.ItemHeight  = SystemInformation.MenuHeight + extraHeight;
165             if ( topLevel )
166                 e.ItemWidth  = textwidth - 5
167             else
168                 e.ItemWidth   = Math.Max(160, textwidth + 50);
169             itemHeight = e.ItemHeight;
170             base.OnMeasureItem(e);
171         }
172         
173         
174         protected override void OnDrawItem(DrawItemEventArgs e) 
175         {   
176             Graphics g = e.Graphics;
177             Rectangle bounds = e.Bounds;
178             bool selected = (e.State & DrawItemState.Selected) > 0;
179             bool toplevel = (Parent == Parent.GetMainMenu());
180             bool hasicon  = Icon != null;
181             bool enabled = Enabled;
182             DrawBackground(g, bounds, e.State, toplevel, hasicon, enabled);
183             if (hasicon)
184                 DrawIcon(g, Icon, bounds, selected, Enabled, Checked);
185             else
186             {
187                 if (Checked)
188                     DrawCheckmark(g, bounds, selected);
189                 if (RadioCheck)
190                     DrawRadioCheckmark(g, bounds, selected);
191             }
192 
193             if (Text == "-"
194             { DrawSeparator(g, bounds);    } 
195             else 
196             {
197                 DrawMenuText(g, bounds, Text, shortcuttext, Enabled, toplevel, e.State); 
198             }
199         }
200 
201         private void DrawRadioCheckmark(Graphics g, Rectangle bounds, bool selected) 
202         {//绘制单选框
203             int checkTop = bounds.Top + (itemHeight - BITMAP_SIZE)/2;
204             int checkLeft = bounds.Left + ( STRIPE_WIDTH - BITMAP_SIZE)/2;
205             ControlPaint.DrawMenuGlyph(g, new Rectangle(checkLeft, checkTop, BITMAP_SIZE, BITMAP_SIZE), MenuGlyph.Bullet);
206             g.DrawRectangle(new Pen(framecolor), checkLeft-1, checkTop-1, BITMAP_SIZE+1, BITMAP_SIZE+1);
207         }
208         private void DrawCheckmark(Graphics g, Rectangle bounds, bool selected) 
209         {//绘制选择框
210             int checkTop = bounds.Top + (itemHeight - BITMAP_SIZE)/2;
211             int checkLeft = bounds.Left + ( STRIPE_WIDTH - BITMAP_SIZE)/2;
212             ControlPaint.DrawMenuGlyph(g, new Rectangle(checkLeft, checkTop, BITMAP_SIZE, BITMAP_SIZE), MenuGlyph.Checkmark);
213             g.DrawRectangle(new Pen(framecolor), checkLeft-1, checkTop-1, BITMAP_SIZE+1, BITMAP_SIZE+1);
214         }
215 
216         private void DrawIcon(Graphics g, Image icon, Rectangle bounds, bool selected, bool enabled, bool ischecked) 
217         {//绘制图片
218             int iconTop = bounds.Top + (itemHeight - BITMAP_SIZE)/2;
219             int iconLeft = bounds.Left + (STRIPE_WIDTH - BITMAP_SIZE)/2;
220             if (enabled) 
221             {
222                 if (selected) 
223                 {
224                     ControlPaint.DrawImageDisabled(g, icon, iconLeft + 1, iconTop, Color.Black);
225                     g.DrawImage(icon, iconLeft, iconTop - 1);
226                 } 
227                 else 
228                 {
229                     g.DrawImage(icon, iconLeft + 1, iconTop);
230                 }
231             } 
232             else 
233             {
234                 ControlPaint.DrawImageDisabled(g, icon, iconLeft + 1, iconTop, SystemColors.HighlightText);
235             }
236         }
237     
238         private void DrawSeparator(Graphics g, Rectangle bounds) 
239         {//绘制间隔线
240             int y = bounds.Y + bounds.Height / 2;
241             g.DrawLine(new Pen(SystemColors.ControlDark), bounds.X + iconSize + 7, y, bounds.X + bounds.Width - 2, y);            
242             
243         }
244         
245         private void DrawBackground(Graphics g, Rectangle bounds, DrawItemState state, bool toplevel, bool hasicon, bool enabled) 
246         {//绘制背景
247             bool selected = (state & DrawItemState.Selected) > 0;
248             if (selected || ((state & DrawItemState.HotLight) > 0)) 
249             {
250                 if (toplevel && selected) 
251                 {
252                     bounds.Inflate(-10);
253                     g.FillRectangle(new SolidBrush(SelectionColor), bounds);//区域    
254                     g.DrawRectangle(new Pen(framecolor),bounds);//边框//
255                 //    g.FillRectangle(new LinearGradientBrush(bounds,Color.FromArgb(182,189,210),Color.White,180f),bounds);
256 
257                 ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, bounds.Width, bounds.Height, Border3DStyle.SunkenOuter, Border3DSide.Top | Border3DSide.Left | Border3DSide.Right | Border3DSide.Bottom);
258               
259                 } 
260                 else 
261                 {
262                     if(toplevel)
263                     {//顶层菜单  //有光标时的形状
264                         bounds.Inflate(-10);
265                         g.FillRectangle(new SolidBrush(SelectionColor), bounds);
266                 //        g.DrawRectangle(new Pen(System.Drawing.Color.Blue),bounds);
267                         
268                         ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, bounds.Width, bounds.Height, Border3DStyle.RaisedInner, Border3DSide.Top | Border3DSide.Left | Border3DSide.Right | Border3DSide.Bottom);
269                         
270                     }
271                     else
272                         if (enabled ) 
273                     {
274                         g.FillRectangle(new SolidBrush(selectioncolor), bounds);
275                     //    g.FillRectangle(new SolidBrush(Color.Red), bounds);//区域///////////
276                     //    g.FillRectangle(new LinearGradientBrush(bounds,selectioncolor,Color.White,180f), bounds);
277                         g.DrawRectangle(new Pen(framecolor), bounds.X , bounds.Y, bounds.Width - 1, bounds.Height-1);//??????????????
278                     }
279                     else 
280                     {
281                         g.FillRectangle(new SolidBrush(barcolor), bounds);
282                     //    g.FillRectangle(new LinearGradientBrush(bounds,Color.Blue,Color.White,90f),bounds);  
283                         bounds.X += STRIPE_WIDTH;
284                         bounds.Width -= STRIPE_WIDTH;
285                         g.FillRectangle(new SolidBrush(backcolor), bounds);            
286 
287                          
288                     }
289                 }
290             } 
291             else 
292             {
293                 if (!toplevel) 
294                 {   
295                     int boundsW = bounds.Width;
296                     bounds.Width = STRIPE_WIDTH ;
297                     g.FillRectangle(new SolidBrush(barcolor), bounds);//菜单项左边区域
298                 //    g.FillRectangle(new LinearGradientBrush(bounds,System.Drawing.SystemColors.InactiveCaption,System.Drawing.Color.White,180f),bounds);  //渐变色
299 
300 
301                     bounds.X += STRIPE_WIDTH;
302                     bounds.Width = boundsW;
303                     bounds.Width -= STRIPE_WIDTH;
304                     g.FillRectangle(new SolidBrush(backcolor), bounds);//菜单项右边区域
305                 //    g.FillRectangle(new LinearGradientBrush(bounds,Color.White,Color.Blue,180f),bounds);
306                 } 
307                 else 
308                 {
309                 //    g.FillRectangle(SystemBrushes.Control, bounds);
310                     g.FillRectangle(SystemBrushes.ControlLight, bounds);
311                 }
312             }
313         }
314 
315         private void DrawMenuText(Graphics g, Rectangle bounds, string text, string shortcut, bool enabled, bool toplevel, DrawItemState state )    
316         {//绘制菜单文本
317             bool selected = (state & DrawItemState.Selected) > 0;
318             StringFormat stringformat = new StringFormat();
319             stringformat.HotkeyPrefix = ((state & DrawItemState.NoAccelerator) > 0? HotkeyPrefix.Hide : HotkeyPrefix.Show;
320             if ( toplevel ) 
321             {
322                 int index = text.IndexOf("&");
323                 if ( index != -1 ) 
324                 {
325                     text = text.Remove(index,1);
326                 }
327             }
328             int textwidth = (int)(g.MeasureString(text, SystemInformation.MenuFont).Width);
329             int x = toplevel ? bounds.Left + (bounds.Width - textwidth) / 2: bounds.Left + iconSize + 10;
330             int topGap = 7;
331             if ( toplevel ) topGap = 2;
332             int y = bounds.Top + topGap;
333             Brush brush = null;
334             if (!enabled)
335                 brush = new SolidBrush(SystemColors.GrayText);
336             else 
337                 brush = new SolidBrush(SystemColors.MenuText);
338             g.DrawString(text, SystemInformation.MenuFont, brush, x, y, stringformat);
339             if ( !toplevel ) 
340             {
341                 stringformat.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
342                 g.DrawString(shortcut, SystemInformation.MenuFont, brush, bounds.Width - 10 , bounds.Top + topGap, stringformat);
343             }
344 
345             if(selected && !toplevel)//反白显示
346             {
347                 g.DrawString(text.Replace("&",""),SystemInformation.MenuFont,new SolidBrush(Color.Blue),x,y);
348                 g.DrawString(shortcut, SystemInformation.MenuFont, new SolidBrush(Color.Blue), bounds.Width - 10 , bounds.Top + topGap, stringformat);
349             }
350         }
351     }
352 }
353 

 

如果有什么不足或者存在任何的BUG欢迎提出宝贵意见,本人将近快做出修改;