程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 用c#繪制Office 2003樣式的菜單

用c#繪制Office 2003樣式的菜單

編輯:關於C#

我的方法是重寫MenuItem類,在寫的過程中發現用GDI+實際測量出來的文本的大小不是很准確,還有文本也不能很好對齊,固在代碼裡可以時常看到很多多加上去的數字.我想原理就不用我講了吧,下面的代碼注釋的很清楚了:

CODE:

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace OfficeMenu
{
/// <summary>
/// Class1 的摘要說明。
/// </summary>
public class OfficeMenuItem:MenuItem
{
 public OfficeMenuItem(bool IsApplyOfficeMenu,string ItemText)
 {
 if(IsApplyOfficeMenu)
 {
  this.Text=ItemText;
  this.OwnerDraw=true;
  font=new Font("宋體",9f,GraphicsUnit.Point);
 }
 else
 {
  this.Text=ItemText;
  this.OwnerDraw=false;
 }
 }
 private Font font;
 private StringFormat strFormat=new StringFormat();
 private string ItemText="";
 private string iconPath="";
 //定義繪制的時候的各種筆刷
 private LinearGradientBrush TopMenuHostLightBrush;
 private SolidBrush TopMenuDefaultBrush;
 private SolidBrush FontDefaultBrush;
 private LinearGradientBrush TopMenuSelectedBrush;
 private SolidBrush MenuDefaultBrush;
 private SolidBrush MenuDefaultSelectedBrush;
 private SolidBrush MenuCheckBrush;
 private LinearGradientBrush MenuSideBarBrush;
 private SolidBrush MenuDefaultGrayedBrush;
 //定義繪制的時候所需的各種線條
 private Pen TopMenuPen;
 private Pen MenuDefaultPen;
 //定義需要的矩形結構
 private Rectangle SideBarRect;
 private Rectangle CheckedRect;
 private Rectangle TopMenuRect;
 private Rectangle ShortcutRect;
 //定義圖標
 public string IconPath
 {
 get
 {
  return iconPath;
 }
 set
 {
  iconPath=value;
 }
 }
 //判斷菜單是否是頂級菜單
 private bool CheckIsTop()
 {
 if(typeof(MainMenu)==this.Parent.GetType())
 {
  return true;
 }
 else
 {
  return false;
 }
 }
 //獲取菜單的快捷鍵
 private string GetShortCut()
 {
 string shortcut="";
 try
 {
  if(this.ShowShortcut==true && (!this.IsParent) && (!(this.Shortcut==Shortcut.None)))
  {
  shortcut=this.Shortcut.ToString();
  shortcut=shortcut.Replace("Ctrl","Ctrl+");
  shortcut=shortcut.Replace("Alt","Alt+");
  shortcut=shortcut.Replace("Shift","Shift+");
  }
 }
 catch
 {
  return "";
 }
 return shortcut;
 }
 //重寫測量函數
 protected override void OnMeasureItem(MeasureItemEventArgs e)
 {
 base.OnMeasureItem (e);
 try
 {
  ItemText=this.Text;
  SizeF SizeMenuText;
  if(this.ItemText=="-") //設置分割線的高度
  {
  e.ItemHeight=5;
  return;
  }
  string getedShortcut=this.GetShortCut();
  if(!this.CheckIsTop()) //如果不是頂級菜單
  {
  SizeMenuText=e.Graphics.MeasureString(ItemText+"".PadRight(4,' ')+getedShortcut,this.font);
  e.ItemWidth=Convert.ToInt32(SizeMenuText.Width)+26;
  }
  else
  {
  SizeMenuText=e.Graphics.MeasureString(ItemText,this.font);
  e.ItemWidth=Convert.ToInt32(SizeMenuText.Width)-4;
  }
  if(this.Visible)
  {
  e.ItemHeight=Convert.ToInt32(SizeMenuText.Height)+6;
  }
  else
  {
  e.ItemHeight=0;
  }
 }
 catch
 {
  e.ItemHeight=20;
  e.ItemWidth=80;
 }
 }
 //重寫繪圖函數
 protected override void OnDrawItem(DrawItemEventArgs e)
 {
 if(this.Visible)
 {
  base.OnDrawItem (e);
  Rectangle MenuRect=e.Bounds;
  ItemText=this.Text;
  Graphics g=e.Graphics;
  //繪制邊框時需要的特殊矩形
  SideBarRect=new Rectangle(MenuRect.X,MenuRect.Y,25,MenuRect.Height);
  //繪制選擇框時需要的矩形
  CheckedRect=new Rectangle(MenuRect.X+1,MenuRect.Y+1,24,MenuRect.Height-2);
  //繪制頂菜單時需要的矩形
  TopMenuRect=new Rectangle(MenuRect.X+1,MenuRect.Y+3,MenuRect.Width,MenuRect.Height);
  //繪制shortcut用到的矩形
  ShortcutRect=new Rectangle(MenuRect.X,MenuRect.Y+4,MenuRect.Width-10,MenuRect.Height);
  //定義繪制的時候的各種筆刷
  TopMenuHostLightBrush=new LinearGradientBrush(MenuRect,Color.White,Color.FromArgb(220,134,56),90f); //頂級菜單發生HOTLIGHT 時顯示的顏色
  TopMenuDefaultBrush=new SolidBrush(SystemColors.Control); //頂級菜單默認的顏色
  FontDefaultBrush=new SolidBrush(Color.Black); //字體默認的顏色
  TopMenuSelectedBrush=new LinearGradientBrush(MenuRect,Color.White,Color.FromArgb(95,109,126),90f); //頂級菜單選中時的顏色
  MenuDefaultBrush=new SolidBrush(Color.White); //默認菜單的顏色
  MenuDefaultSelectedBrush=new SolidBrush(Color.FromArgb(247,218,157)); //菜單選中時的顏色
  MenuCheckBrush=new SolidBrush(Color.FromArgb(225,143,70)); //當菜單CHECKED屬性為真的時顯示的顏色
  MenuSideBarBrush=new LinearGradientBrush(SideBarRect,Color.White,Color.FromArgb(149,160,174),0f);//繪制側欄
  MenuDefaultGrayedBrush=new SolidBrush(Color.FromArgb(105,105,105));//菜單不可用時
  //定義繪制的時候所需的各種線條
  TopMenuPen=new Pen(Brushes.Black,1f); //頂級菜單的邊框
  MenuDefaultPen=new Pen(new SolidBrush(Color.FromArgb(60,60,115)),1f); //正常選擇時的邊框
  //開始繪制****************************************************
  if(this.CheckIsTop() && this.ItemText!="-") //如果是頂級菜單
  {
  bool IsDraw=false;//定義一個變量保證正常顯示的只繪制一次 避免浪費資源
  strFormat.Alignment=StringAlignment.Center;
  if(IsDraw==false) //繪制正常顯示時的圖像
  {
   g.FillRectangle(TopMenuDefaultBrush,MenuRect);
   g.DrawString(ItemText,this.font,FontDefaultBrush,TopMenuRect,strFormat);
  }
  //繪制HOTLIGHT時的圖像
  if((e.State & DrawItemState.HotLight)==DrawItemState.HotLight) //突出顯示時
  {
   g.FillRectangle(TopMenuHostLightBrush,MenuRect);
   g.DrawRectangle(TopMenuPen,MenuRect.X,MenuRect.Y,MenuRect.Width-1,MenuRect.Height-1);
   g.DrawString(ItemText,this.font,FontDefaultBrush,TopMenuRect,strFormat);
   IsDraw=true;
  }
  //繪制菜單選中時的圖像
  if((e.State & DrawItemState.Selected)==DrawItemState.Selected)
  {
   g.FillRectangle(TopMenuSelectedBrush,MenuRect);
   g.DrawRectangle(TopMenuPen,MenuRect.X,MenuRect.Y,MenuRect.Width-1,MenuRect.Height-1);
   g.DrawString(ItemText,this.font,FontDefaultBrush,TopMenuRect,strFormat);
   IsDraw=true;
  }
  }
  else //非頂級菜單時
  {
  if(this.ItemText!="-")
  {
   bool IsDraw=false;
   if(IsDraw==false) //正常顯示時
   {
   g.FillRectangle(MenuDefaultBrush,MenuRect);
   g.FillRectangle(MenuSideBarBrush,MenuRect.X,MenuRect.Y,25,MenuRect.Height);
   g.DrawString(ItemText,this.font,FontDefaultBrush,MenuRect.X+26,MenuRect.Y+4);
   //繪制shortcut
   string shortcut=this.GetShortCut();
   strFormat.Alignment=StringAlignment.Far;
   g.DrawString(shortcut,this.font,FontDefaultBrush,ShortcutRect,strFormat);
   //繪制圖標
   this.DrawIcon(g);
   }
   if((e.State & DrawItemState.Selected)==DrawItemState.Selected) //選中時
   {
   this.DrawItem_Selected(g,MenuRect,ItemText);
   IsDraw=true;
   }
   if((e.State & DrawItemState.Grayed)==DrawItemState.Grayed) //不可用時
   {
   g.DrawString(ItemText,this.font,MenuDefaultGrayedBrush,MenuRect.X+26,MenuRect.Y+4);
   IsDraw=true;
   }
   if(!this.IsParent)
   {
   if((e.State & DrawItemState.Checked)==DrawItemState.Checked) //選擇時
   {
    g.FillRectangle(MenuCheckBrush,CheckedRect);
    g.DrawRectangle(new Pen(Brushes.Black,1f),MenuRect.X+1,MenuRect.Y+1,23,MenuRect.Height-3);
    g.DrawString("√",this.font,FontDefaultBrush,MenuRect.X+3,MenuRect.Y+4);
    IsDraw=true;
   }
   if(this.Checked==true && ((e.State & DrawItemState.Selected)==DrawItemState.Selected)) //選中且Checked屬性為真時
   {
    g.FillRectangle(new SolidBrush(Color.FromArgb(255,91,91)),CheckedRect);
    g.DrawRectangle(new Pen(Brushes.Black,1f),MenuRect.X+1,MenuRect.Y+1,23,MenuRect.Height-3);
    g.DrawString("√",this.font,FontDefaultBrush,MenuRect.X+3,MenuRect.Y+4);
    IsDraw=true;
   }
   }
  }
  else //畫分割線
  {
   SolidBrush PartitionLineBrush=new SolidBrush(Color.FromArgb(128,128,128));
   Pen PartitionPen=new Pen(PartitionLineBrush,1f);
   g.FillRectangle(MenuDefaultBrush,MenuRect);
   g.FillRectangle(MenuSideBarBrush,MenuRect.X,MenuRect.Y,25,MenuRect.Height);
   g.DrawLine(PartitionPen,new Point(MenuRect.X+27,MenuRect.Y+2),new Point(MenuRect.X+27+(MenuRect.Width-26),MenuRect.Y+2));
  }
  }
 }
 }
 //畫圖標
 private void DrawIcon(Graphics g)
 {
 if(this.CheckIsTop()==false && this.IconPath!="" && this.IsParent==false && this.Checked==false)
 {
  try
  {
  Bitmap iconImage=new Bitmap(this.IconPath);
  int imageWidth=iconImage.Width;
  int imageHeight=iconImage.Height;
  if(imageWidth<=CheckedRect.Width && imageHeight<=CheckedRect.Height)
  {
   int ImageRecWidthMistake=CheckedRect.Width-imageWidth;
   float Mistake_2=(float)ImageRecWidthMistake/2f;
   g.DrawImage(iconImage,CheckedRect.X+(int)Mistake_2,CheckedRect.Y,imageWidth,imageHeight);
  }
  else
  {
   g.DrawImage(iconImage,CheckedRect);
  }
  }
  catch
  {
  throw new IconNotFindException("不能創建圖標,可能是路徑不能也可能是不支持此格式");
  }
 }
 }
 //由於再繪制的過程中選中的動作時需要執行兩次一樣的代碼 固在這裡用了一個函數
 private void DrawItem_Selected(Graphics g,Rectangle rec,string itemtext)
 {
 SolidBrush tmpBrush;
 if(this.Enabled)
 {
  tmpBrush=FontDefaultBrush;
 }
 else
 {
  tmpBrush=MenuDefaultGrayedBrush;
 }
 //正常顯示
 g.FillRectangle(MenuDefaultSelectedBrush,rec);
 g.DrawRectangle(MenuDefaultPen,rec.X,rec.Y,rec.Width-1,rec.Height-1);
 g.DrawString(itemtext,this.font,tmpBrush,rec.X+26,rec.Y+4);
 //顯示shortcut
 string shortcut=this.GetShortCut();
 strFormat.Alignment=StringAlignment.Far;
 g.DrawString(shortcut,this.font,tmpBrush,ShortcutRect,strFormat);
 //畫圖標
 this.DrawIcon(g);
 }
}
//自定義異常
public class IconNotFindException:ApplicationException
{
 public IconNotFindException(string message)
 :base(message)
 {
 }
}
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved