n°达达的主页1234n.com个人博客 / 旧文存档
← 返回文章
2005-12-18 / 达达

C#实现带图标菜单(2006-3-22 新增示例代码与可执行文件)

分享C#WindowsGDI+
    本文与《 C#获取文件与文件夹默认图标 》为同一系列,示例代码为同一个程序。

    相关的资料我在Google上搜索了一下,好像找不到详细一点的中文资料,只好跑到国外的网站学习了一下,做了一个类似资源管理器功能的菜单,如下图所示。在这里总结下做带图标菜单的经验,让大家少走些弯路。
图片尚未恢复
  首先我从MenuItem继承,编写了一个自己的MenuItem类,在构造函数中将OwnerDraw属性设置为true 如果没有设置这个属性MenuItem的OnDrawItem事件将不会被执行,不信可以自己设置断点看看。接下来就是在OnDrawItem事件中重写MenuItem的绘制代码。根据我们的需要,除了绘制边框和文字外还要绘制菜单的图标。绘图的代码如下所示:
 
 protected   override   void  OnDrawItem(DrawItemEventArgs e) 
  { 
      try 
        { 
          // 绘制菜单项底色 
          e.Graphics.FillRectangle(BackColor, e.Bounds.X, e.Bounds.Y, 
         e.Bounds.Width + 1 , e.Bounds.Height + 1 ); 
          // 绘制菜单图标底色 
          e.Graphics.FillRectangle(IconBackColor, e.Bounds.X, e.Bounds.Y,  20 , e.Bounds.Height + 1 ); 

          if ( base .Text  ==   " - " ) 
           { 
             e.Graphics.FillRectangle(IconBackColor, e.Bounds.X + 20 , 
             e.Bounds.Y + 2 , e.Bounds.Width - 20 , e.Bounds.Height - 2 ); 
         } 
          else 
            { 
             Rectangle _rectIcon  = new  Rectangle(e.Bounds.X + 1 , e.Bounds.Y + 2 ,  16 ,  16 ); 

              // 绘制图标 
               if (ItemIcon  !=   null ) 
             e.Graphics.DrawIconUnstretched(ItemIcon, _rectIcon); 

             e.Graphics.DrawString( base .Text, e.Font, TextColor, e.Bounds.X + 22 , e.Bounds.Y + 2 ); 

              // 处于选中状态时绘制被选择项高亮显示效果 
               if ((e.State  &  DrawItemState.Selected)  !=   0 ) 
               { 
                 e.Graphics.FillRectangle(SelectedColor, e.Bounds); 
                 e.Graphics.DrawRectangle(SelectedBroder, e.Bounds.X, e.Bounds.Y, 
                 e.Bounds.Width - 1 , e.Bounds.Height - 1 ); 
             } 
         } 
     } 
      catch (Exception _ex) 
       { 
     } 
 } 
 
 
上面用到的自定义菜单项属性有:
 
 public  Icon ItemIcon  =   null  ;   //  菜单图标  
 private   static  Brush BackColor  =   Brushes.White;   //  背景色  
 private   static  Brush TextColor  =   Brushes.Black;   //  文本颜色  
 private   static  Brush IconBackColor  =   Brushes.LightBlue;   //  图标背景色  
 private   static  Brush SelectedColor  =   new  Pen(Color.FromArgb(  80  , 
Color.LightBlue.R,Color.LightBlue.G,Color.LightBlue.B)).Brush;  //  被选中状态高亮颜色  
 private   static  Pen SelectedBroder   =   Pens.SkyBlue;  //  被选中状态高亮边框颜色  
 
我第一次做时就这么做完然后执行了,结果显示出来的是一个小的可怜的小矩形,没有图标也没有文字,后来跑去仔细看看别人的做法时才知道要重写OnMeasureItem事件的代码才能正确获取菜单的大小,以下是OnMeasureItem事件中的代码,我几乎原封不动从别人那里Copy过来的图片尚未恢复:
   protected   override   void  OnMeasureItem(MeasureItemEventArgs e) 
  { 
      try 
        { 
          if ( base .Text  ==   " - " ) 
           { 
             e.ItemHeight  =   4 ; 
         } 
          else 
            { 
             e.ItemHeight  =   18 ; 
             e.ItemWidth  =  Convert.ToInt32(e.Graphics.MeasureString( this .Text, TextFont).Width) + 30 ; 
         } 
     } 
      catch (Exception x) 
       { 
     } 
 } 
 
就这样带图标的菜单可以正常显示了~~呵呵~~不信自己试试看,至于我怎么获取图中的分区信息以及文件和文件夹图标的,我会在后续文章中介绍。

    本文与《C#获取文件与文件夹默认图标》为同一系列,示例代码为同一个程序。

示例代码下载地址:https://files.cnblogs.com/BG5SBK/[2005-12-13-01]%20XView.rar
示例程序下载地址:https://files.cnblogs.com/BG5SBK/XView_Bin.rar

标签按正文匹配本站已有分类。本文按博客园原文恢复排版,并接回已核实的本地图片。查看恢复说明

原文:博客园 · BG5SBK。按原发表日期收录。旧交互演示以静态内容保留。