程序|创建|控件|柱形图
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. 在"调试"菜单上单击"开始执行(不调试)"。
编译该应用程序并将其部署到目标设备上(与运行时所需的任何其他库一起),然后在设备上启动该应用程序。
执行结果如下:

ZEhHTML5中文学习网 - HTML5先行者学习网ZEhHTML5中文学习网 - HTML5先行者学习网