flatstyle按钮自己做
和c或vb比起来,使用c#写自定义控件,特别是从零开始写自定义控件,不知简化了多少倍,没有复杂而晦涩的消息映射,思路就像写应用程序一样如行云流水,一路畅通。学过delphi的人都知道有一套flatstyle控件,平面式的简约风格给用户带来了良好的视觉效果。但是看看他的源码,如果没有一定的windows底层功底,看起来可不是件容易的事。现在好了,有了c#这个异常强大的工具,我们就可以轻轻松松的写一个自己的flatstyle控件了。
本文以平面按钮为例,写一个按钮颜色和边框颜色能任意更改的自定义按钮控件,希望能起到抛砖引玉的作用。
如果我们只是改变已有的控件的外观(如本例),那么最好继承原有的控件。如:
public class buttonlzh : system.windows.forms.button
定义一个枚举类型,用来描述鼠标的状态:
protected enum status
{
mouseenter,
mouseleave,
mousedown,
mouseup
}
写一个画文字的函数:
protected void drawstring(string strtext,graphics g)
{
stringformat sf=new stringformat();
sf.linealignment=stringalignment.center;
sf.alignment=stringalignment.center;
g.drawstring(strtext,this.font,new solidbrush(color.blue),this.clientrectangle,sf);
}
填充按钮颜色及画边框颜色:
protected void drawborder(status status,graphics g)
{
pen[] mousepen=new pen[4];//定义四支笔
mousepen[(int)status.mousedown]=new pen(_mousedownbordercolor,2);
mousepen[(int)status.mouseenter]=new pen(_mouseenterbordercolor,2);
mousepen[(int)status.mouseleave]=new pen(_mouseleavebordercolor,2);
mousepen[(int)status.mouseup]=new pen(_mouseupbordercolor,2);
solidbrush[] mousebrush=new solidbrush[4];//定义四个笔刷
mousebrush[(int)status.mousedown]=new solidbrush(_mousedowncolor);
mousebrush[(int)status.mouseenter]=new solidbrush(_mouseentercolor);
mousebrush[(int)status.mouseleave]=new solidbrush(_mouseleavecolor);
mousebrush[(int)status.mouseup]=new solidbrush(_mouseupcolor);
switch(status)
{
case status.mousedown:
g.fillrectangle(mousebrush[(int)status.mousedown],this.clientrectangle);
g.drawrectangle(mousepen[(int)status.mousedown],this.clientrectangle);
break;
case status.mouseenter:
g.fillrectangle(mousebrush[(int)status.mouseenter],this.clientrectangle);
g.drawrectangle(mousepen[(int)status.mouseenter],this.clientrectangle);
break;
case status.mouseleave:
g.fillrectangle(mousebrush[(int)status.mouseleave],this.clientrectangle);
g.drawrectangle(mousepen[(int)status.mouseleave],this.clientrectangle);
break;
case status.mouseup:
g.fillrectangle(mousebrush[(int)status.mouseup],this.clientrectangle);
g.drawrectangle(mousepen[(int)status.mouseup],this.clientrectangle);
break;
}
for(int i=0;i<4;i++)
{
mousepen[i].dispose();
mousebrush[i].dispose();
}
}
重载onpaint()事件:
protected override void onpaint(painteventargs e)
{
base.onpaint (e);
graphics g=e.graphics;
switch(mousestatus)
{
case status.mousedown:
this.drawborder(status.mousedown,g);
this.drawstring(this.text,g);
break;
case status.mouseenter:
this.drawborder(status.mouseenter,g);
this.drawstring(this.text,g);
break;
case status.mouseleave:
this.drawborder(status.mouseleave,g);
this.drawstring(this.text,g);
break;
case status.mouseup:
this.drawborder(status.mouseup,g);
this.drawstring(this.text,g);
break;
}
}
基本的函数就是这样了,无外乎就是画边框,然后填充颜色。当我们重载了onpaint()事件后,也就等于把按钮的外观绘制权交到了自己的手里,你想怎么画就怎么画啦。
以下是程序的所有源码,新建一个windows控件库,把代码复制过去就ok!
using system;
using system.collections;
using system.componentmodel;
using system.drawing;
using system.data;
using system.windows.forms;
namespace lzhbutton
{
/// <summary>
/// usercontrol1 的摘要说明。
/// </summary>
public class buttonlzh : system.windows.forms.button
{
private color _mouseentercolor;
private color _mouseleavecolor;
private color _mousedowncolor;
private color _mouseupcolor;
private color _mouseenterbordercolor;
private color _mouseleavebordercolor;
private color _mousedownbordercolor;
private color _mouseupbordercolor;
private status mousestatus;
[description("鼠标进入控件内的颜色"),category("appearance")]
public color mouseentercolor
{
get
{
return _mouseentercolor;
}
set
{
_mouseentercolor=value;
}
}
[description("鼠标移出控件外的颜色"),category("appearance")]
public color mouseleavecolor
{
get
{
return _mouseleavecolor;
}
set
{
_mouseleavecolor=value;
}
}
[description("鼠标按下时按钮的颜色"),category("appearance")]
public color mousedowncolor
{
get
{
return _mousedowncolor;
}
set
{
_mousedowncolor=value;
}
}
[description("鼠标弹起时按钮的颜色"),category("appearance")]
public color mouseupcolor
{
get
{
return _mouseupcolor;
}
set
{
_mouseupcolor=value;
}
}
/////////////////////////////////////////////
[description("鼠标进入按钮时的边框颜色"),category("appearance")]
public color mouseenterbordercolor
{
get
{
return _mouseenterbordercolor;
}
set
{
_mouseenterbordercolor=value;
}
}
[description("鼠标移出按钮的边框颜色"),category("appearance")]
public color mouseleavebordercolor
{
get
{
return _mouseleavebordercolor;
}
set
{
_mouseleavebordercolor=value;
}
}
[description("鼠标按下按钮的边框颜色"),category("appearance")]
public color mousedownbordercolor
{
get
{
return _mousedownbordercolor;
}
set
{
_mousedownbordercolor=value;
}
}
[description("鼠标弹起时按钮的边框颜色"),category("appearance")]
public color mouseupbordercolor
{
get
{
return _mouseupbordercolor;
}
set
{
_mouseupbordercolor=value;
}
}
/// <summary>
/// 必需的设计器变量。
/// </summary>
private system.componentmodel.container components = null;
public buttonlzh()
{
// 该调用是 windows.forms 窗体设计器所必需的。
initializecomponent();
// todo: 在 initcomponent 调用后添加任何初始化
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.dispose();
}
base.dispose( disposing );
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 – 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void initializecomponent()
{
//
// buttonlzh
//
this.mouseup += new system.windows.forms.mouseeventhandler(this.buttonlzh_mouseup);
this.mouseenter += new system.eventhandler(this.buttonlzh_mouseenter);
this.mouseleave += new system.eventhandler(this.buttonlzh_mouseleave);
this.mousedown += new system.windows.forms.mouseeventhandler(this.buttonlzh_mousedown);
//初始化
_mouseentercolor=color.yellow;
_mouseleavecolor=color.pink;
_mousedowncolor=color.red;
_mouseupcolor=color.blue;
_mouseenterbordercolor=color.greenyellow;
_mouseleavebordercolor=color.deeppink;
_mousedownbordercolor=color.palevioletred;
_mouseupbordercolor=color.cadetblue;
}
#endregion
protected enum status
{
mouseenter,
mouseleave,
mousedown,
mouseup
}
/// <summary>
/// 画文字
/// </summary>
/// <param name="strtext">要画的文字</param>
/// <param name="g">画布</param>
protected void drawstring(string strtext,graphics g)
{
stringformat sf=new stringformat();
sf.linealignment=stringalignment.center;
sf.alignment=stringalignment.center;
g.drawstring(strtext,this.font,new solidbrush(color.blue),this.clientrectangle,sf);
}
/// <summary>
/// 画边框
/// </summary>
/// <param name="status">鼠标状态</param>
/// <param name="g">画布</param>
protected void drawborder(status status,graphics g)
{
pen[] mousepen=new pen[4];//定义四支笔
mousepen[(int)status.mousedown]=new pen(_mousedownbordercolor,2);
mousepen[(int)status.mouseenter]=new pen(_mouseenterbordercolor,2);
mousepen[(int)status.mouseleave]=new pen(_mouseleavebordercolor,2);
mousepen[(int)status.mouseup]=new pen(_mouseupbordercolor,2);
solidbrush[] mousebrush=new solidbrush[4];//定义四个笔刷
mousebrush[(int)status.mousedown]=new solidbrush(_mousedowncolor);
mousebrush[(int)status.mouseenter]=new solidbrush(_mouseentercolor);
mousebrush[(int)status.mouseleave]=new solidbrush(_mouseleavecolor);
mousebrush[(int)status.mouseup]=new solidbrush(_mouseupcolor);
switch(status)
{
case status.mousedown:
g.fillrectangle(mousebrush[(int)status.mousedown],this.clientrectangle);
g.drawrectangle(mousepen[(int)status.mousedown],this.clientrectangle);
break;
case status.mouseenter:
g.fillrectangle(mousebrush[(int)status.mouseenter],this.clientrectangle);
g.drawrectangle(mousepen[(int)status.mouseenter],this.clientrectangle);
break;
case status.mouseleave:
g.fillrectangle(mousebrush[(int)status.mouseleave],this.clientrectangle);
g.drawrectangle(mousepen[(int)status.mouseleave],this.clientrectangle);
break;
case status.mouseup:
g.fillrectangle(mousebrush[(int)status.mouseup],this.clientrectangle);
g.drawrectangle(mousepen[(int)status.mouseup],this.clientrectangle);
break;
}
for(int i=0;i<4;i++)
{
mousepen[i].dispose();
mousebrush[i].dispose();
}
}
/// <summary>
/// 重载onpaint事件
/// </summary>
/// <param name="e"></param>
protected override void onpaint(painteventargs e)
{
base.onpaint (e);
graphics g=e.graphics;
switch(mousestatus)
{
case status.mousedown:
this.drawborder(status.mousedown,g);
this.drawstring(this.text,g);
break;
case status.mouseenter:
this.drawborder(status.mouseenter,g);
this.drawstring(this.text,g);
break;
case status.mouseleave:
this.drawborder(status.mouseleave,g);
this.drawstring(this.text,g);
break;
case status.mouseup:
this.drawborder(status.mouseup,g);
this.drawstring(this.text,g);
break;
}
}
private void buttonlzh_mousedown(object sender, system.windows.forms.mouseeventargs e)
{
mousestatus=status.mousedown;
this.invalidate();
}
private void buttonlzh_mouseenter(object sender, system.eventargs e)
{
mousestatus=status.mouseenter ;
this.invalidate();
}
private void buttonlzh_mouseleave(object sender, system.eventargs e)
{
mousestatus=status.mouseleave;
this.invalidate();
}
private void buttonlzh_mouseup(object sender, system.windows.forms.mouseeventargs e)
{
mousestatus=status.mouseup;
this.invalidate();
}
}
}
