通过.NET类库来重画Windows标准控件

发表于:2007-05-26来源:作者:点击数: 标签:
概述: 当你在全新体验 Windows XP 令人赏心悦目的界面的时候,你一定在想"如果我的程序界面也都能这么漂亮,那该多好啊"。那就让我们来看看到底应该如何通过.NET类库来重画Windows标准控件。 本文通过两个例子来阐述如何通过程序编码来有效的改变Windows标

  概述:
  当你在全新体验Windows XP令人赏心悦目的界面的时候,你一定在想"如果我的程序界面也都能这么漂亮,那该多好啊"。那就让我们来看看到底应该如何通过.NET类库来重画Windows标准控件。
  
  本文通过两个例子来阐述如何通过程序编码来有效的改变Windows标准控件外观。
  
  平台需求
  Visual Studio .NET
  Visual C# .NET
  
  例1:改变控件属性
  使用Visual Studio .NET来开发软件时,可以利用其强大的IDE环境来手工设定界面控件的属性。但是如果你要使你整个程序上的控件风格都是某种特定属性的话,那最好的方法就是自己重载控件类。
  
  让我们从最简单的System.Windows.Forms.Button类开始尝试,按钮有如下的常用属性:
  
  BackColor--按钮的背景颜色
  
  Cursor--鼠标状态
  
  Enabled--是否启用按钮
  
  FlatStyle--按钮的扁平风格
  
  Font--按钮上的字体
  
  ForeColor--按钮的前景颜色
  
  Height--按钮的高度
  
  Image--按钮上的图片
  
  Location--按钮上的位置
  
  Text--按钮上的文字
  
  Visible--按钮是否可见
  
  Width--按钮的宽度
  
  在下面的这个例子里面,我们得到一个蓝底白字的扁平按钮:
  
  1、在Visual C# .NET中新建一个Windows Application项目,命名为OwnDrawButton1;
  
  2、往项目中添加一个MyButton类,将其改为继承System.Windows.Forms.Button,并在构造函数中添加修改属性的代码;
  
  就像这样:
  
  public class MyButton : System.Windows.Forms.Button
  {
  public MyButton()
  {
  //set the back color to blue
  BackColor = System.Drawing.Color.Blue;
  //set the appearance style to flat
  FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  //use system default font
  Font = System.Windows.Forms.Control.DefaultFont;
  //use white color to write text and draw the border
  ForeColor = System.Drawing.Color.White;
  }
  }
  
  3、拖一个按钮到Form1上,右击鼠标,单击"View Code",在代码中用"MyButton"替换掉"System.Windows.Forms.Button";
  
  4、编译执行。
  
  现在,你就能在你的界面上看到自定义的控件了(如图1)。
  
  图1 通过代码修改控件属性的按钮
  
  例2:重画简单控件
  仅通过改变控件的属性值来自定义控件,在很多情况下是不能令人满意的。例如如果想把Windows XP里那种风格的按钮放到Windows 98/2000下,你就得自己来画那些按钮了。
  
  在这种情况下,你可以通过重载OnPaint()等事件来重画按钮。你也可以通过EventHandler来让控件响应更多的事件,例如,我们可以给按钮添加鼠标悬停效果,给MouseEnter和MouseLeave分别加上EeventHandler,这样,你在事件响应函数里写的代码就会被调用。
  
  下面是一个例子,这个例子编写了一个类似Windows XP中按钮风格的控件:
  
  1、在Visual C# .NET中新建一个Windows Application项目,命名为OwnDrawButton2;
  
  2、往项目中添加一个MyButton类,将其改为继承System.Windows.Forms.Button,在构造函数中添加修改属性的代码和事件响应关联代码,并编写各函数代码,如下所列:
  
  using System;
  using System.Drawing;
  using System.Windows;
  using System.Windows.Forms;
  
  namespace OwnDrawButton2
  {
  public class MyButton : System.Windows.Forms.Button
  {
  //state variable for mouse down
  private bool mouseDown=false;
  
  //state variable for mouse hover
  private bool mouseHover=false;
  
  public MyButton()
  {
  //set the control UserPaint
  SetStyle(ControlStyles.UserPaint,true);
  
  //EventHandler for MouseDown
  MouseDown+=new MouseEventHandler(OnMouseDown);
  
  //EventHandler for MouseUp
  MouseUp+=new MouseEventHandler(OnMouseUp);
  
  //EventHandler for MouseEnter
  MouseEnter+=new EventHandler(OnMouseEnter);
  
  //EventHandler for MouseLeave
  MouseLeave+=new EventHandler(OnMouseLeave);
  
  Height=23;//Default Height
  Width=75;//Default Width
  }
  
  protected override void OnPaint(PaintEventArgs pe)
  {
  //first, paint the control with parent form's background color
  pe.Graphics.FillRectangle(new SolidBrush(Parent.BackColor),
  pe.ClipRectangle);
  
  //if the button is disabled, draw the disable style
  if (Enabled == false)
  {
  DrawDisableButton(pe.Graphics);
  }
  else if (mouseDown)
  {
  //when mouse down, draw the mouse down style
  DrawMouseDownButton(pe.Graphics);
  }
  else if (mouseHover)
  {
  //when mouse hover, draw the mouse hover style
  DrawMouseHoverButton(pe.Graphics);
  }
  else if (Focused)
  {
  //when mouse is focused but not mouse hover,
  //draw the focus style
  DrawContainFocusButton(pe.Graphics);
  }
  else//else, draw the normal style
  {
  DrawNormalButton(pe.Graphics);
  }
  WriteText(pe.Graphics);//write text
  }
  private void OnMouseDown(object sender,MouseEventArgs e)
  {
  mouseDown=true; //mouse is down now
  }
  
  private void OnMouseUp(object sender,MouseEventArgs e)
  {
  mouseDown=false; //mouse is up now
  
  //call paint action
  PaintEventArgs pe =
  new PaintEventArgs(CreateGraphics(),ClientRectangle);
  
  OnPaint(pe);
  }
  
  private void OnMouseEnter(object sender,EventArgs e)
  {
  mouseHover=true; //mouse hover on
  
  //call paint action
  PaintEventArgs pe =
  new PaintEventArgs(CreateGraphics(),ClientRectangle);
  
  OnPaint(pe);
  }
  
  private void OnMouseLeave(object sender,EventArgs e)
  {
  mouseHover=false; //mouse is not hover on
  
  //call paint action
  PaintEventArgs pe =
  new PaintEventArgs(CreateGraphics(),ClientRectangle);
  
  OnPaint(pe);
  }
  
  private void DrawBorder(Graphics g,int state)
  {
  if (state==1)//draw normal style broder
  {
  Pen p = new Pen(SystemColors.ControlLightLight,2);
  g.DrawLine(p,1,1,1,Height-2);
  g.DrawLine(p,1,1,Width-2,1);
  g.DrawLine(p,Width-1,2,Width-1,Height-2);
  g.DrawLine(p,2,Height-1,Width-2,Height-1);
  }
  else if (state==2)//draw hover style border
  {
  Pen p = new Pen(Color.Yellow,2);
  g.DrawLine(p,1,1,1,Height-2);
  g.DrawLine(p,1,1,Width-2,1);
  g.DrawLine(p,Width-1,2,Width-1,Height-2);
  g.DrawLine(p,2,Height-1,Width-2,Height-1);
  }
  else if (state==3)//draw pressed style border
  {
  Pen p = new Pen(SystemColors.ControlDark,2);
  g.DrawLine(p,1,1,1,Height-2);
  g.DrawLine(p,1,1,Width-2,1);
  g.DrawLine(p,Width-1,2,Width-1,Height-2);
  g.DrawLine(p,2,Height-1,Width-2,Height-1);
  }
  else if (state==4)//draw disabled style border
  {
  Pen p = new Pen(SystemColors.ControlLight,2);
  g.DrawLine(p,1,1,1,Height-2);
  g.DrawLine(p,1,1,Width-2,1);
  g.DrawLine(p,Width-1,2,Width-1,Height-2);
  g.DrawLine(p,2,Height-1,Width-2,Height-1);
  }
  else if (state==5)//draw default style border
  {
  Pen p = new Pen(Color.SkyBlue,2);
  g.DrawLine(p,1,1,1,Height-2);
  g.DrawLine(p,1,1,Width-2,1);
  g.DrawLine(p,Width-1,2,Width-1,Height-2);
  g.DrawLine(p,2,Height-1,Width-2,Height-1);
  }
  if (state==4)//draw disable style border
  {
  Pen p = new Pen(Color.FromArgb(161,161,146),1);
  g.DrawLine(p,0,2,0,Height-3);
  g.DrawLine(p,2,0,Width-3,0);
  g.DrawLine(p,Width-1,2,Width-1,Height-3);
  g.DrawLine(p,2,Height-1,Width-3,Height-1);
  g.DrawLine(p,0,2,2,0);
  g.DrawLine(p,0,Height-3,2,Height-1);
  g.DrawLine(p,Width-3,0,Width-1,2);
  g.DrawLine(p,Width-3,Height-1,Width-1,Height-3);
  }
  else//draw normal style border
  {
  g.DrawLine(Pens.Black,0,2,0,Height-3);
  g.DrawLine(Pens.Black,2,0,Width-3,0);
  g.DrawLine(Pens.Black,Width-1,2,Width-1,Height-3);
  g.DrawLine(Pens.Black,2,Height-1,Width-3,Height-1);
  g.DrawLine(Pens.Black,0,2,2,0);
  g.DrawLine(Pens.Black,0,Height-3,2,Height-1);
  g.DrawLine(Pens.Black,Width-3,0,Width-1,2);
  g.DrawLine(Pens.Black,Width-3,Height-1,
  Width-1,Height-3);
  }
  }
  
  private void DrawNormalButton(Graphics g)//draw normal style button
  {
  //draw normal style border
  DrawBorder(g,1);
  
  //paint background
  PaintBack(g,SystemColors.ControlLightLight);
  }
  
  private void DrawMouseHoverButton(Graphics g)
  {
  //draw mouse hover style border
  DrawBorder(g,2);
  
  //paint background
  PaintBack(g,SystemColors.ControlLightLight);
  }
  
  private void DrawMouseDownButton(Graphics g)
  {
  //draw mouse down style border
  DrawBorder(g,3);
  
  //paint background
  PaintBack(g,SystemColors.ControlLight);
  }
  
  private void DrawDisableButton(Graphics g)
  {
  //draw disable style border
  DrawBorder(g,4);
  
  //paint background
  PaintBack(g,SystemColors.ControlLight);
  }
  
  private void DrawContainFocusButton(Graphics g)
  {
  //draw contain focuse style border
  DrawBorder(g,5);
  
  //paint background
  PaintBack(g,SystemColors.ControlLightLight);
  }
  
  //paint background area of the button
  private void PaintBack(Graphics g,Color c)
  {
  g.FillRectangle(new SolidBrush(c),3,3,
  Width-6,Height-6);
  }
  
  private void WriteText(Graphics g)
  {
  //calculate the text position
  int x=0,y=0;
  Size s = g.MeasureString(Text,Font).ToSize();
  x=(Width-s.Width)/2;
  y=(Height-s.Height)/2;
  
  //draw text
  if (Enabled) //is enabled, draw black text
  g.DrawString(Text,Font,Brushes.Black,x,y);
  else //not enabled, draw gray text
  g.DrawString(Text,Font,Brushes.Gray,x,y);
  }
  }
  }
  
  3、在新控件的构造函数中添加:拖3个按钮到Form1上,将其中一个的"Enable"设为"false",右击鼠标,单击"View Code",在代码中用"MyButton"替换掉"System.Windows.Forms.Button";
  
  4、编译执行。

原文转自:http://www.ltesting.net