vs.net本身并不提供智能设备(如pda)应用程序的柱形图,开发智能设备应用程序时vs.net并不象window应用程序那样提供用户自定义控件。在本文中,您将创建一个以柱形图显示的 pdachartcontrol自定义控件。还将创建一个使用此 pdachartcontrol自定义控件的智能设备应用程序。为了完成开发工作,您将执行这些过程:
· 创建该 pdachartcontrol 自定义控件的运行时版本。
· 编译该 pdachartcontrol 自定义控件的设计时版本。
· 将该控件添加到工具箱中。
· 创建一个使用该 pdachartcontrol 自定义控件的智能设备应用程序。
· 在智能设备应用程序中测试该控件。
本文的重点不在于编写控件的代码,而在于如何创建设计时自定义控件以及如何将它添加到"工具箱"中。
生成自定义控件
第一步是使用智能设备类库模板创建新项目并生成控件。
创建自定义控件
1. 在"文件"菜单上指向"新建",然后单击"项目"。
2. 在"新建项目"对话框中的"项目类型"下,单击"visual c# 项目",并在"模板"下单击"智能设备应用程序"。
3. 在"名称"框中,键入"pdachartcontrolcontrol",然后单击"确定"。
4. 在"智能设备应用程序向导"中,单击上窗格中的"pocket pc"和下窗格中的"类库",然后单击"确定"。
创建了一个新项目,class1.cs 在代码编辑器中打开。
由于已经创建用于该控件的项目,接下来可以向项目中添加引用、更改代码以及编译 pdachartcontrol 自定义控件的运行时版本。
编译自定义控件的运行时版本
1. 在解决方案资源管理器中,右击 class1.cs 并单击"重命名"。
2. 重命名文件 pdachartcontrolcontrol.cs。
注意 如果没有打开解决方案资源管理器,请单击"视图"菜单上的"解决方案资源管理器"。
用下列代码替换 pdachartcontrolcontrol.cs 中的代码:
//*************************************
// pdachartcontrolcontrol
using system;
using system.collections;
using system.componentmodel;
using system.drawing;
using system.data;
using system.windows.forms;
using system.drawing.drawing2d;
#if netcfdesigntime
[assembly: system.cf.design.runtimeassemblyattribute("pdachartcontrol, version=1.10.0.0, _
culture=neutral, publickeytoken=null")]
namespace pdachartcontrol
{
/// <summary>
/// summary description for usercontrol1.
/// </summary>
public class pdachart : system.windows.forms.control
{
public system.windows.forms.hscrollbar hscrollbar1;
/// <summary>
/// required designer variable.
/// </summary>
// delegate declaration.
// public delegate void eventhandler(string text,color backcolor,int height);
//
// //声明事件的委托:
// //public delegate void myeventhandler(string text,color backcolor,int height);
// //定义一个公共事件成员
// public event eventhandler addcube;
// protected virtual void onaddcube(eventargs e)
// {
//
// }
//
private pdachartcontrol.mygraph objgraph=new mygraph();
private point mbeginpoint=new point(0,0) ;
private system.componentmodel.container components = null;
public pdachart()
{
initializecomponent();
}
public enum charttypeenum { pillarchart, cakechart ,breaklinkchart};
#region windows 属性定义
private bool mhscrollbarvisible=true;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.defaultvalueattribute(0)]
[system.componentmodel.description("设置/读取滚动条是否可见")]
#endif
public bool hscrollbarvisible
{
get
{
return mhscrollbarvisible;
}
set
{
mhscrollbarvisible =value;
this.invalidate();
}
}
private charttypeenum mcharttype=charttypeenum.pillarchart;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.defaultvalueattribute(0)]
[system.componentmodel.description("设置/读取图形类型")]
#endif
public charttypeenum charttype
{
get
{
return mcharttype;
}
set
{
mcharttype =value;
this.invalidate();
}
}
private int mpicheight=20;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.defaultvalueattribute(0)]
[system.componentmodel.description("设置/读取饼图高")]
#endif
public int picheight
{
get
{
return mpicheight;
}
set
{
mpicheight =value;
this.invalidate();
}
}
private font mtitlefont =new font("arial", 9, fontstyle.regular);
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.description("设置/读取文本字体")]
#endif
public font titlefont
{
get
{
return mtitlefont;
}
set
{
mtitlefont=value;
this.invalidate();
}
}
private font mtextfont =new font("arial", 8, fontstyle.regular);
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.description("设置/读取文本字体")]
#endif
public font textfont
{
get
{
return mtextfont;
}
set
{
mtextfont=value;
this.invalidate();
}
}
private static datatable mdatatable=new datatable() ;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.description("设置/读取数据表")]
#endif
public datatable datatable
{
get
{
return mdatatable;
}
set
{
mdatatable=(datatable)value;
this.invalidate();
}
}
private string mshowcolumnname;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.description("设置/读取显示列")]
#endif
public string showcolumnname
{
get
{
return mshowcolumnname;
}
set
{
mshowcolumnname=value;
this.invalidate();
}
}
private string mdatacolumnname;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.description("设置/读取数据列")]
#endif
public string datacolumnname
{
get
{
return mdatacolumnname;
}
set
{
mdatacolumnname=value;
this.invalidate();
}
}
private string mtitle="统计图";
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.defaultvalueattribute("图表")]
[system.componentmodel.description("设置/读取标题")]
#endif
public string title
{
get
{
return mtitle;
}
set
{
mtitle=value;
this.invalidate();
}
}
private arraylist mcubedata;
#if !netcfdesigntime
//the actual data used to draw the line on the graph
public icollection cubedata
{
get
{
return mcubedata;
}
set
{
mcubedata = new arraylist(value);
rectangle rcclient = this.clientrectangle;
rectangle rcgraphclient = new rectangle(rcclient.x + 21, rcclient.y + 5, rcclient.width - 21, rcclient.height - 21);
this.invalidate(rcgraphclient);
}
}
#endif
private color mbackcolor=system.drawing.systemcolors.controllight;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.defaultvalueattribute(0)]
[system.componentmodel.description("设置/读取背景颜色")]
#endif
public override color backcolor
{
get
{
return mbackcolor;
}
set
{
mbackcolor =value;
this.invalidate();
}
}
private color maxesxcolor=system.drawing.systemcolors.highlighttext;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.defaultvalueattribute(0)]
[system.componentmodel.description("设置/读取x轴颜色")]
#endif
public color axesxcolor
{
get
{
return maxesxcolor;
}
set
{
maxesxcolor =value;
this.invalidate();
}
}
private color maxesycolor=system.drawing.systemcolors.info;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.defaultvalueattribute(0)]
[system.componentmodel.description("设置/读取y轴颜色")]
#endif
public color axesycolor
{
get
{
return maxesycolor;
}
set
{
maxesycolor =value;
this.invalidate();
}
}
private int mlenght = 4;
#if netcfdesigntime
// these design time attributes affect appearance of this property in the property grid.
[system.componentmodel.defaultvalueattribute(5)]
[system.componentmodel.description("立体长")]
#endif
//the lower y bound of the pdachart
public int lenght
{
get
{
return mlenght;
}
set
{
mlenght = value;
this.invalidate();
}
}
private int mmaxyvalue ;//图表y轴最大值
private int mmaxxvalue ;//图表x轴最大值
private color mgridlinecolor=system.drawing.color.cyan;
#if netcfdesigntime
[system.componentmodel.category("pdachart")]
[system.componentmodel.description("网格线的颜色.")]
#endif
//the color of the line of the pdachart.
public color gridlinecolor
{
get
{
return mgridlinecolor;
}
set
{
mgridlinecolor =value;
this.invalidate();
}
}
private bool mshowxtext = true;
#if netcfdesigntime
// these design time attributes affect appearance of this property in the property grid.
[system.componentmodel.category("chart")]
[system.componentmodel.defaultvalueattribute(true)]
[system.componentmodel.description("是否显示x轴的文本")]
#endif
// if true, shows the y-values on the left of the pdachart
public bool isshowxtext
{
get
{
return mshowxtext;
}
set
{
mshowxtext = value;
this.invalidate();
}
}
private bool mshowytext = true;
#if netcfdesigntime
// these design time attributes affect appearance of this property in the property grid.
[system.componentmodel.category("chart")]
[system.componentmodel.defaultvalueattribute(true)]
[system.componentmodel.description("是否显示y轴的数字")]
#endif
// if true, shows the y-values on the left of the pdachart
public bool isshowytext
{
get
{
return mshowytext;
}
set
{
mshowytext = value;
this.invalidate();
}
}
private bool mshowxscale = true;
#if netcfdesigntime
// these design time attributes affect appearance of this property in the property grid.
[system.componentmodel.category("chart")]
[system.componentmodel.defaultvalueattribute(true)]
[system.componentmodel.description("是否显示x轴的刻度.")]
#endif
// if true, shows the x-values on the bottom of the pdachart
public bool isshowxscale
{
get
{
return mshowxscale;
}
set
{
mshowxscale = value;
this.invalidate();
}
}
private bool mshowyscale = true;
#if netcfdesigntime
// these design time attributes affect appearance of this property in the property grid.
[system.componentmodel.category("chart")]
[system.componentmodel.defaultvalueattribute(true)]
[system.componentmodel.description("是否显示y轴的刻度")]
#endif
// if true, shows the y-values on the left of the pdachart
public bool isshowyscale
{
get
{
return mshowyscale;
}
set
{
mshowyscale = value;
this.invalidate();
}
}
private bool mshowgrid = true;
#if netcfdesigntime
// these design time attributes affect appearance of this property in the property grid.
[system.componentmodel.category("chart")]
[system.componentmodel.defaultvalueattribute(false)]
[system.componentmodel.description("是否显示网格线")]
#endif
// if true, shows horiztonal grid lines on the pdachart.
public bool isshowgrid
{
get
{
return mshowgrid;
}
set
{
mshowgrid = value;
this.invalidate();
}
}
#endregion
/// <summary>
/// clean up any resources being used.
/// </summary>
protected override void dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.dispose();
}
base.dispose( disposing );
}
#region component designer generated code
/// <summary>
/// required method for designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void initializecomponent()
{
this.paint += new system.windows.forms.painteventhandler(this.onpaint);
this.hscrollbar1 = new system.windows.forms.hscrollbar();
this.hscrollbar1.location = new system.drawing.point(1, 100);
this.hscrollbar1.maximum = 1;
this.hscrollbar1.largechange = 1;
this.hscrollbar1.size = new system.drawing.size(100, 16);
this.hscrollbar1.valuechanged += new system.eventhandler(this.hscrollbar1_valuechanged);
this.controls.add(this.hscrollbar1);
}
#endregion
//
// private arraylist mcudedata;
protected override void onresize(eventargs e)
{
//this.refresh();
}
graphics mgraphics;
pen mblackpen=new pen(color.black);
//偏差
int topheightwarp=16; //顶偏差(文本高)
int leftwidthwarp=0; //左偏差(最大数据文本宽)
int underheightwarp=10; //底偏差(底文本高)
int betweenlineheight=10;//水平线的高
int linecount=10;//水平线数
// //this paint function uses routines common to both platforms.
int clientheight;
int mwidth;
int yheight;
rectangle rcclient;
system.drawing.region region1;
public void onpaint(object sender, system.windows.forms.painteventargs e)
{
//base.paint(null,e);
mgraphics=e.graphics;
//读取数据
this.rcclient = this.clientrectangle;
region1=new region ( this.rcclient);
region1=region1.clone();
clientheight=rcclient.height;
objgraph.mgraphics=e.graphics; //mgraphics.measurestring//
//计算最大的x轴、y轴坐标
countmaxscalexscaley();
underheightwarp=(int)objgraph.mgraphics.measurestring("文本",this.mtextfont).height+5;
underheightwarp+=this.hscrollbar1.height;
//作图的范围区(开始点、长、宽、高)
mbeginpoint.x =this.clientrectangle.x+leftwidthwarp ;
mbeginpoint.y =this.clientrectangle.y+rcclient.height-underheightwarp ;
//写标题
drawtitle(rcclient);
int width=rcclient.width-this.mlenght-leftwidthwarp;
mwidth=width;
int height=rcclient.height-this.mlenght-topheightwarp-underheightwarp;
this.yheight= height;
int lenght=this.mlenght;
//设置流动条
// this.hscrollbar1.location = new system.drawing.point(0, rcclient.y+rcclient.height);
initpage();
if (this.hscrollbarvisible)
{
this.hscrollbar1.left=0;
this.hscrollbar1.top=rcclient.height-this.hscrollbar1.height ;
this.hscrollbar1.maximum=this.pagecount-1;
if(rcclient.width<246)
this.hscrollbar1.width= rcclient.width;
else
this.hscrollbar1.width=246;
}
else
{
this.hscrollbar1.left=0;
this.hscrollbar1.top=0 ;
}
//从此分别画图
if (this.mmaxyvalue>10)
{
//水平网络线
this.betweenlineheight=(int)objgraph.mgraphics.measurestring("文本",this.mtextfont).height;
this.linecount=height/betweenlineheight;
}
else
{
this.betweenlineheight=height/10;
//线数应该是能整
this.linecount=10;
}
//画与它父相同背景颜色的区域,以隐藏角边
color parentbackcolor=color.brown;
objgraph.drawrectangle( parentbackcolor,new point(0,0),rcclient.width,rcclient.height);
e.graphics.drawrectangle(new pen(parentbackcolor), rcclient);
objgraph.drawpdachart(this.mgridlinecolor, this.maxesxcolor,this.maxesycolor,_
this.mbackcolor,mbeginpoint,lenght,width,height, this.mshowxscale,this.mshowyscale);
//画线和左文本(内部左下点)
point p=mbeginpoint;
p.x+=this.mlenght;
p.y-=this.mlenght;
drawgridlineandtexts(p,width);
//mbeginpoint
//画矩形与写文本
//createcubes(mbeginpoint,width,rcclient.height);
//mbeginpoint.x+=10;
createpagecubes(mbeginpoint,width,clientheight);
drawtitle(rcclient);
}
}
//以左下坐标p,颜色color,长lenght,宽width,高height,x轴文本textx,画立体图
public void addonecube(string textx,point p,color color,int lenght,int width, int height)
{
try
{
objgraph.drawcube (color,p,lenght,width,height);
//文本
int txtwidth=(int)objgraph.mgraphics.measurestring(textx,mtextfont).width;
int txtheight=(int)objgraph.mgraphics.measurestring(textx,mtextfont).height;
int x=(p.x+width/2)-txtwidth/2;
int y=p.y+txtheight/2;
this.objgraph.drawtext(textx,color.black,this.mtextfont,x,y-5);
}
catch(exception ex)
{
string str=ex.message;
}}
//一页立方体图形个数
int onepagecubecount=10;
int currentpage=0;//当前页
int pagecount=0;//多少页
//水平轴的相对值
int xscale;
//y轴的相对值
double yscale=0.2;
color[] color={color.red,color.blue,color.green,color.yellow,color.yellowgreen,color.magenta,_
color.cyan,color.coral,color.slategray,color.pink,color.crimson,color.dodgerblue,color.chartreuse };
//计算页
private void initpage()
{
if(this.onepagecubecount==0) return;
if (mdatatable.rows.count<onepagecubecount)
this.onepagecubecount=mdatatable.rows.count ;
if(this.onepagecubecount==0) return;
pagecount=mdatatable.rows.count/this.onepagecubecount;
//水平轴的相对值
xscale=width/this.onepagecubecount ;
//y轴的相对值
if(this.mmaxyvalue<=0) return;
{
if(this.mmaxyvalue==0) return;
this.yscale=double.parse(this.yheight.tostring())/double.parse( this.mmaxyvalue.tostring() ) ;//system.math.
//this.yscale=double.parse(this.yscale.tostring())/double.parse(this.linecount.tostring() );
}
// this.yscale=double.parse(system.convert.tostring(1))/double.parse( this.mmaxyvalue.tostring() ) ;//system.math.
}
private void hscrollbar1_valuechanged(object sender, system.eventargs e)
{
//onpaint(object sender, system.windows.forms.painteventargs e)
//清画出的图
this.currentpage=hscrollbar1.value;
// if (mgraphics.clip==null)
// {
mgraphics=this.creategraphics ();
this.objgraph.mgraphics=mgraphics;
// }
//mgraphics.clip=this.region1;
//画矩形与写文本,最多一屏
//mgraphics.clear(this.mbackcolor) ;
//mgraphics.resetclip();
//createpagecubes(mbeginpoint,width,clientheight);
system.windows.forms.painteventargs e1=new painteventargs( mgraphics,this.rcclient);
onpaint(null,e1);
}
public void nextpage()
{
this.objgraph.mgraphics=this.creategraphics ();
this.currentpage++;
bitmap bm = new bitmap(10,10);
graphics g = graphics.fromimage(bm);
if (this.currentpage>this.pagecount)
this.currentpage--;
//画矩形与写文本,最多一屏
//mgraphics.clear(color.red) ;
//mgraphics.resetclip();
createpagecubes(mbeginpoint,width,clientheight);
}
//在左下顶点,宽width,高height建立立方体
private void createpagecubes(point beginp ,int width,int height)
{
if(mdatatable.rows.count==0) return;
int between=10;
switch(this.onepagecubecount)
{
case 1:
between= mwidth/2;
break;
case 2:
between= mwidth/3;
break;
case 3:
between= mwidth/4;
break;
case 4:
between= mwidth/5;
break;
case 5:
between= mwidth/6;
break;
case 6:
between= mwidth/7;
break;
case 7:
between= mwidth/8-1;
break;
case 8:
between= mwidth/9-2;
break;
case 9:
between=mwidth/9-5;
break;
case 10:
between=mwidth/10-5;
break;
}
int rowindex=this.onepagecubecount*this.currentpage;
point p=beginp;//dr.
p.x-=8;
for ( int i=0;i<this.onepagecubecount;i++ )
{
//p.x= this.xscale*(i+1)+10;
p.x+=between+this.mlenght;
double cubeheight=this.yscale*system.convert.toint32(mdatatable.rows[rowindex][this.mdatacolumnname]);
//if ((p.x >= 0) && (p.x <= width) && (p.y >= 0) && (p.y <= height))
//{
string text=mdatatable.rows[rowindex][this.mshowcolumnname].tostring() ;
string data=mdatatable.rows[rowindex][this.mdatacolumnname].tostring() ;
int colorindex=rowindex;
if (colorindex>=color.length)
colorindex=color.length-1;
if (this.mshowxtext==false) text=" ";
addonecube(text,p,color[i],this.mlenght,this.mlenght+4,system.convert.toint32(cubeheight));
//}
rowindex++;
}
}
//在左下顶点,宽width,高height建立立方体
private void createcubes(point beginp ,int width,int height)
{
if(mdatatable.rows.count==0) return;
//水平轴的相对值
int xscale=width/mdatatable.rows.count ;
//y轴的相对值
if(this.mmaxyvalue<=0) return;
int yscale=height/(this.mmaxyvalue*this.linecount) ;
int rowindex=0;
color[] color={color.red,color.blue,color.green,color.yellow,color.yellowgreen,color.magenta,_
color.cyan,color.coral,color.slategray,color.pink,color.crimson,color.dodgerblue,color.chartreuse };
foreach(datarow dr in mdatatable.rows)
{
rowindex+=1;
point p=beginp;//dr.
p.x= xscale*rowindex+10;
int cubeheight=yscale*system.convert.toint32(dr[this.mdatacolumnname]);
if ((p.x >= 0) && (p.x <= width) && (p.y >= 0) && (p.y <= height))
{
string text=dr[this.mshowcolumnname].tostring() ;
string data=dr[this.mdatacolumnname].tostring() ;
int colorindex=rowindex;
if (colorindex>=color.length)
colorindex=color.length-1;
if (this.mshowxtext==false) text=" ";
addonecube(text,p,color[colorindex-1],this.mlenght,this.mlenght+5,cubeheight);
//objgraph.drawcube (color,p,this.mlenght,width,height);
}
}
}
//计算最大的x、y轴坐标,左边文本宽,最小的线高
private void countmaxscalexscaley()
{
if(mdatatable.rows.count==0) return;
this.mmaxxvalue=mdatatable.rows.count ;
this.mmaxyvalue=0;
//this.l.
foreach(datarow dr in mdatatable.rows)
{
int cubeheight=system.convert.toint32(dr[this.mdatacolumnname]);
if (mmaxyvalue<cubeheight)
{
mmaxyvalue=cubeheight;
}
int textwidth=(int)objgraph.mgraphics.measurestring(system.convert.todouble( dr[this.mdatacolumnname])._
tostring() ,this.mtextfont).width+10;
if (leftwidthwarp<textwidth)
{
leftwidthwarp=textwidth;
}
}
//leftwidthwarp+=10;
}
//在顶部中心位置写标题
private void drawtitle(rectangle rcclient)
{
int width=(int)objgraph.mgraphics.measurestring(this.mtitle,mtitlefont).width;
int height=(int)objgraph.mgraphics.measurestring(this.mtitle,mtitlefont).height;
this.topheightwarp=height;
int x=rcclient.width/2- width/2;
int y=rcclient.y+height/2-5;
this.objgraph.drawtext(this.mtitle,color.blue,mtitlefont,x,y);
}
//画所有水平网络线
//p:起始点;width:线宽;betweenheight:二线之间高,count:线数
// private void drawgridlineandtexts(point p,int width)
// {
// for(int i=0;i<this.linecount;i++)
// {
// drawgridlineandtext(p,p,width,lenght);
// p.y-=betweenheight;
// }
// }
//由顶点与长、宽、高画颜色为color,背景色为的backcolor图表(3d)
private void drawgridlineandtexts(point p,int width)
{//是否显示网络水平线
if (this.mshowgrid)
{
this.objgraph.drawgridlines(this.mgridlinecolor,p,width-1,this.mlenght,this.betweenlineheight,this.linecount);
}
//是否显示左文本
if (this.mshowytext)
{
point p1=p;
//p1.x-=this.mlenght;
p1.y+=lenght;
double a1=double.parse(system.convert.tostring(this.linecount-1));
double a2=double.parse(this.mmaxyvalue.tostring());
double a=system.math.round(a2/a1,1);
for(int i=0;i<this.linecount;i++)
{
string text=system.convert.tostring(a*(i+1));
int txtwidth=(int)objgraph.mgraphics.measurestring(text,this.mtextfont).width;
p1.x=p.x-txtwidth-this.mlenght;;
p1.y-=this.betweenlineheight;
this.objgraph.drawtext(text,color.black,this.mtextfont,p1.x,p1.y);
}
}
}
//求数据列的和
private double sumcolumn(datatable dt,string columnname)
{
double sum=0.0;
foreach(datarow dr in dt.rows)
{
sum+=system.convert.todouble(dr[columnname]);
}
return sum;
}
}
#region
public class mygraph
{
//网络水平线中二线之间的高
//int betweenlineheight=20;
//最大maxycount:线数
// int maximumy=10;
// int lenght=5;
// int width=200;
// int height=300;
// bool isshowgrid=true;
public graphics mgraphics;
//背景色
// public color backcolor= system.drawing.systemcolors.control;
// //x轴颜色
// public color axesxcolor=system.drawing.systemcolors.highlighttext;
// //y轴颜色
// public color axesycolor=system.drawing.systemcolors.info;
//黑色笔
private pen mblackpen = new system.drawing.pen(color.fromargb(0,0,0));
//网格线笔
private pen mgridpen= new system.drawing.pen(color.fromargb(127, 127, 127));
//color backcolor= system.drawing.color.fromargb(((system.byte)(224)), ((system.byte)(224)), ((system.byte)(224)));
public mygraph()
{
//mgraphics=this.creategraphics(); //
// todo: 在此处添加构造函数逻辑
//
}
//由左下顶点与宽、高画颜色为color的平行四边形
public void drawrectangle3dtop(color color, point leftunderpoint,int width,int height)
{
try
{
//计算左上顶点
point p1=new point ();
p1.x=leftunderpoint.x+height;
p1.y=leftunderpoint.y-height;
//计算右上顶点
point p2=new point ();
p2.x=leftunderpoint.x+width+height;
p2.y=leftunderpoint.y-height;
//计算右下顶点
point p3=new point ();
p3.x=leftunderpoint.x+width;
p3.y=leftunderpoint.y;
point[] curvepoints =
{
leftunderpoint,
p1,
p2,
p3
};
// define fill mode.
//fillmode newfillmode = fillmode.winding;
// fill polygon to screen.
// create solid brush.
solidbrush brush = new solidbrush(color);
mgraphics.fillpolygon(brush, curvepoints);
//mgraphics.fillpolygon(brush, curvepoints, newfillmode);
//画边框
mgraphics.drawpolygon(this.mblackpen, curvepoints);
}
catch(exception ex)
{
string str=ex.message;
}
}
//由左下顶点与宽、高画颜色为color的平等四边形
public void drawrectangle3dright(color color, point leftunderpoint,int width,int height)
{
try
{
// create solid brush.
solidbrush brush = new solidbrush(color);
//计算左上顶点
point p1=new point ();
p1.x=leftunderpoint.x;
p1.y=leftunderpoint.y-height;
//计算右上顶点
point p2=new point ();
p2.x=p1.x+width;
p2.y=p1.y-width;
//计算右下顶点
point p3=new point ();
p3.x=leftunderpoint.x+width;
p3.y=leftunderpoint.y-width;
point[] curvepoints =
{
leftunderpoint,
p1,
p2,
p3
};
// define fill mode.
//fillmode newfillmode = fillmode.winding;
// fill polygon to screen.
mgraphics.fillpolygon(brush, curvepoints);
//画边框
mgraphics.drawpolygon(this.mblackpen, curvepoints);
//mgraphics.fillpolygon(brush, curvepoints, newfillmode);
}
catch(exception ex)
{
string str=ex.message;
}
}
//由左上角顶点与宽、高画颜色为color的平行四边形
public void drawrectangle(color color, point p,int width,int height)
{
rectangle rectangle1=new rectangle( p.x,p.y, width,height);
// create solid brush.
solidbrush brush = new solidbrush(color);
// fill polygon to screen.
mgraphics.fillrectangle(brush, rectangle1);
//画边框
mgraphics.drawrectangle(this.mblackpen,rectangle1);
}
//由左下顶点与长、宽、高画颜色为color的立方图形(3d)
public void drawcube(color color, point leftunderpoint,int lenght,int width,int height)
{
// create solid brush.
solidbrush brush = new solidbrush(color);
point lefttoppoint= leftunderpoint;
lefttoppoint.y-= height;
drawrectangle3dtop(color,lefttoppoint,width,lenght);
drawrectangle(color,lefttoppoint,width,height);
point rightp=leftunderpoint;
rightp.x+=width;
drawrectangle3dright(color.black,rightp,lenght,height);
}
//画x轴
public void drawaxesx(color color, point p,int width,int height)
{
drawrectangle3dtop(color,p,width,height);
}
//画y轴
public void drawaxesy(color color, point p,int width,int height)
{
drawrectangle3dright(color,p,width,height);
}
//由顶点与长、宽、高画颜色为color,背景色为的backcolor图表(3d)
public void drawpdachart(color gridlinecolor,color axesxcolor,color axesycolor,_
color backcolor,point p,int lenght,int width,int height,bool isshowaxesx,bool isshowaxesy)
{
if(isshowaxesx)
{
//画x轴
drawaxesx(axesxcolor,p,width,lenght);
}
if(isshowaxesy)
{
//画y轴
drawaxesy(axesycolor,p,lenght,height);
}
////画图形区
point prectangle=p;
prectangle.x+=lenght;
prectangle.y-=lenght;
prectangle.y-=height;
drawrectangle(backcolor,prectangle,width,height);
}
//画一条水平网络线与对应的折线
public void drawgridline(color gridlinecolor,point p,int width,int lenght)
{
//draw the y scale;
point endp=p;
endp.x+=width;
pen pen=new pen( gridlinecolor);
//this.mgraphics.drawline(pen,p,endp);
//水平线
this.mgraphics.drawline(pen,p.x,p.y,endp.x,endp.y );
//左折线
this.mgraphics.drawline(pen,p.x,p.y,endp.x-lenght,endp.y+lenght );
}
//画所有水平网络线
//p:起始点;width:线宽;betweenheight:二线之间高,count:线数
public void drawgridlines(color gridlinecolor,point p,int width,int lenght,int betweenheight,int count)
{
pen pen=new pen( gridlinecolor);
for(int i=0;i<count;i++)
{
//drawgridline(gridlinecolor,p,width,lenght);
//水平线
this.mgraphics.drawline(pen,p.x,p.y,p.x+width,p.y );
//左折线
this.mgraphics.drawline(pen,p.x-lenght+1,p.y+lenght,p.x,p.y);
p.y-=betweenheight;
}
}
//在位置(x,y)处以颜色color、字体font写文本text
public void drawtext(string text,color color, font font,int x,int y)
{
// create solid brush.
solidbrush brush = new solidbrush(color);
this.mgraphics.drawstring(text, font, brush, x ,y);
}
//由点p(矩形左上角点),宽piewidth,高pieheight,颜色color画馅饼图
public void drawcake(color color,point p,int piewidth,int pielenght,int pieheight)
{
pen penblack=new pen( color.black);
//黑色最下面的椭圓
rectangle rc1 =new rectangle(p.x,p.y+pieheight,piewidth,pielenght);
this.mgraphics.drawellipse(penblack,rc1);
solidbrush objbrush = new solidbrush(color);
for(int i=0;i<pieheight;i++)
{
this.mgraphics.fillellipse(objbrush,p.x,p.y+i,piewidth,pielenght);
}
//黑色最上面的椭圓
rectangle rc =new rectangle(p.x,p.y,piewidth,pielenght);
this.mgraphics.drawellipse(penblack,rc);
this.mgraphics.drawline( penblack,p.x,p.y+pielenght/2,p.x,p.y+pieheight+pielenght/2);
this.mgraphics.drawline( penblack,p.x+piewidth,p.y+pielenght/2,p.x+piewidth,p.y+pieheight+pielenght/2);
}
//求隋圆任意一点x坐标的相对点
//角angle,中心点opoint,a,长半轴,b,短半轴
public double getellipsepx(double angle,int a,int b)
{
//角
double radians = angle * (math.pi/180);
double px=a*system.math.cos(radians) ;
return px;
}
//求隋圆任意一点y坐标的相对点
//角angle,中心点opoint,a,长半轴,b,短半轴
public double getellipsepy(double angle,int a,int b)
{
//角
double radians = angle * (math.pi/180);
double py=b*system.math.sin(radians);
return py;
}
//画线椭圆线
//角angle,中心点opoint,a,长半轴,b,短半轴
public void drawellipseline(double angle,point opoint,int a,int b)
{
int px=system.convert.toint32(getellipsepx(angle,a,b))+opoint.x ;
int py=system.convert.toint32(getellipsepy(angle,a,b))+opoint.y ;
pen penblack=new pen( color.black);
this.mgraphics.drawline( penblack,opoint.x,opoint.y,px,py);
//e.graphics.drawline( penblack,opoint.x,opoint.y,opoint.x+b,opoint.y);
}
//取扇形的点集(逆时针)
//角angle,已经画过的角finishangle,中心点opoint,长半轴a,短半轴b
public arraylist getpicpoints(double angle,double finishangle,point opoint,int a,int b)
{
//point[system.convert.toint32(angle)] curvepoints=new array() ;
//以步长为1求扇形弧线的坐标点
arraylist plist=new arraylist() ;
plist.add(opoint);
//plist.add(arcstartpoint);
for(int i=0;i<system.convert.toint32(angle);i++)
{
int px=system.convert.toint32(getellipsepx(i+finishangle,a,b))+opoint.x ;
int py=system.convert.toint32(getellipsepy(i+finishangle,a,b))+opoint.y ;
plist.add(new point(px,py));
//curvepoints.setvalue(
}
return plist;
}
//画扇形(逆时针)
//角度angle,已经画过的角finishangle,中心点opoint,长半轴a,短半轴b
public void drawpdapic(color color, string text,double angle,double finishangle,point opoint,int a,int b)
{
// create solid brush.
solidbrush brush = new solidbrush(color);
arraylist plist=getpicpoints(angle,finishangle,opoint,a,b);
point[] curvepoints=new point[plist.count] ;
for(int i=0;i<plist.count;i++)
curvepoints[i]=(point)plist[i];
mgraphics.fillpolygon(brush, curvepoints);
//画边框
mgraphics.drawpolygon(this.mblackpen, curvepoints);
//drawtext(text,color.black,this.
}
}
#endregion
3. 在解决方案资源管理器中,右击"引用",然后单击"添加引用"。
4. 在"添加引用"对话框中的".net"选项卡上,单击"system.drawing",然后单击"选择"。
"system.drawing"会出现在"选定的组件"下。
5. 对"system.windows.forms"重复步骤 4 并单击"确定"。
"system.drawing"和"system.windows.forms"都会出现在解决方案资源管理器的"引用"下。
6. 在"生成"菜单上,单击"生成解决方案"。
将生成控件 pdachartcontrolcontrol.dll 的运行时版本并将其放在目录 projects_directory/pdachartcontrolcontro/bin/debug/ 中。
7. 在"文件"菜单中,单击"关闭解决方案"。
由于生成了控件的运行时版本,接下来可以为设计器支持生成设计时版本。
生成自定义控件的设计时版本
1. 打开 visual studio .net 命令提示。
注意 要打开 visual studio .net 命令提示,请单击"开始",再依次指向"程序"、"microsoft visual studio .net 2003"和"visual studio .net 工具",然后单击"visual studio .net 命令提示"。
2. 切换到包含 pdachartcontrolcontrol.cs 的目录。
3. 在命令提示处键入以下内容:
csc /noconfig /define:netcfdesigntime /target:library /out:design.pdachartcontrolcontrol.dll pdachartcontrolcontrol.cs /r:"c:/program files/microsoft visual studio .net 2003/compactframeworksdk/v1.0.5000/windows ce/designer/system.cf.design.dll" /r:"c:/program files/microsoft visual studio .net 2003/compactframeworksdk/v1.0.5000/windows ce/designer/system.cf.windows.forms.dll" /r:"c:/program files/microsoft visual studio .net 2003/compactframeworksdk/v1.0.5000/windows ce/designer/system.cf.drawing.dll" /r:system.windows.forms.dll /r:system.drawing.dll /r:system.dll /r:system.xml.dll /r:system.web.services.dll /r:system.data.dll /nowarn:1595
这将生成自定义控件的设计时版本。文件 design.pdachartcontrolcontrol.dll 放置在当前目录中。
将自定义控件添加到工具箱
由于编译了控件的运行时和设计时版本,接下来可以将该控件添加到"工具箱",并在智能设备应用程序中使用它了。
将自定义控件添加到"工具箱" 的步骤:
1. 将文件 design.pdachartcontrolcontrol.dll 复制到目录 program files/microsoft visual studio .net 2003/compactframeworksdk/v1.0.5000/windows ce/designer 中。
2. 将文件 pdachartcontrolcontrol.dll 复制到目录 program files/microsoft visual studio .net 2003/compactframeworksdk/v1.0.5000/windows ce 中。
3. 在"视图"菜单上单击"工具箱"。
4. 右击"常规",然后单击"显示所有选项卡"。
5. 单击"设备控件"以显示设备上可用控件的完整列表。
6. 右击"指针",然后单击"添加/移除项"。
7. 在"自定义工具箱"对话框的".net framework 组件"选项卡上,单击"浏览"。
8. 选择"design.pdachartcontrolcontrol.dll"并单击"打开",将"pdachartcontrol"控件添加到"自定义工具箱"对话框中的组件列表。
9. 在 .net framework 组件列表中选择"pdachartcontrol"控件,然后单击"确定"。
"pdachartcontrol"控件即被添加到"工具箱"中。
测试自定义控件
由于自定义控件出现在"工具箱"中,接下来可以使用 windows 窗体设计器将它拖到窗体上。
将自定义控件添加到窗体
1. 在"文件"菜单上指向"新建",然后单击"项目"。
2. 在"新建项目"对话框中的"项目类型"下,单击"visual c# 项目",并在"模板"下单击"智能设备应用程序"。
3. 在"名称"框中,键入"pdachartcontrolcontroltest",然后单击"确定"。
4. 在"智能设备应用程序向导"中,单击上窗格中的"pocket pc"和下窗格中的"windows 应用程序",然后单击"确定"。
创建了新项目,form1.cs 在设计器中打开。
5. 从工具箱将"pdachartcontrol"控件拖到窗体上。
自定义控件即被添加到窗体上,指向 pdachartcontrolcontrol 的引用则被添加到项目中。
注意 如果工具箱不可见,则在"查看"菜单上,单击"工具箱"。
自动生成的代码如下:
pdachartcontrol.pdachart mygraph=new pdachartcontrol.pdachart();
this.pdachart1.axesxcolor = system.drawing.systemcolors.highlighttext;
this.pdachart1.axesycolor = system.drawing.systemcolors.info;
this.pdachart1.backcolor = system.drawing.systemcolors.controllight;
this.pdachart1.charttype = pdachartcontrol.pdachart.charttypeenum.cakechart;
this.pdachart1.datacolumnname = "dataid";
this.pdachart1.gridlinecolor = system.drawing.color.cyan;
this.pdachart1.hscrollbarvisible = true;
this.pdachart1.isshowgrid = true;
this.pdachart1.location = new system.drawing.point(8, 24);
this.pdachart1.picheight = 20;
this.pdachart1.showcolumnname = "showid";
this.pdachart1.size = new system.drawing.size(224, 240);
this.pdachart1.text = "pdachart1";
this.pdachart1.textfont = new system.drawing.font("arial", 8f, system.drawing.fontstyle.regular);
this.pdachart1.title = "统计图";
this.pdachart1.titlefont = new system.drawing.font("arial", 9f, system.drawing.fontstyle.regular);
this.pdachart1.hscrollbar1.visible=false;
this.controls.add(this.pdachart1);
6. 生成测试数据
//测试数据
this.pdachart1.datatable=createquerytable();
this.pdachart1.datacolumnname= "dataid";
this.pdachart1.showcolumnname= "showid";
//建立查询明细表
private datatable createquerytable()
{
datatable dt=new datatable("query");
dt.columns.add("dataid");
dt.columns.add("showid");
for(int i=0;i<10;i++)
{
datarow dr=dt.newrow();
dr["dataid"]=(i+1)*10;
dr["showid"]=(i+1).tostring() ;
dt.rows.add(dr);
}
return dt;
}
7. 在"设备"工具栏的"部署设备"框中,选择要用作目标的设备。
8. 在"调试"菜单上单击"开始执行(不调试)"。
编译该应用程序并将其部署到目标设备上(与运行时所需的任何其他库一起),然后在设备上启动该应用程序。
执行结果如下: