一般的 Windows Form 通常是运用各种控件来显示数据
然而如果您希望在窗体中加入特殊效果来凸显数据内容
那么图形与动画将是非常不错的选择
一般来说我们会使用 Net Framework中 的 GDI+ 函式库来制作图形与动画效果在 GDI+ 还没有推出之前如果要产生二维的 向量图形影像以及印刷样式必须使用旧版操作系统中的GDI新的 GDI+ 是 Windows XP 的一部份除了加入新功能之外还最佳化现有功能以便具体改进 GDI(也就是旧版 Windows 包含的绘图装置接口)的效能
程序范例
图表
图表
图表
我们的程序范例示范了三种动画效果分别是眨眼效果弹跳的球以及文字闪烁当程序执行时会自动展示第一种眨眼效果如图表到所示
运用之前「如何利用程序代码动态存取组件信息」的技巧将组件的 AsmFQName 属性值指派给窗体的 Text 属性并将先前已经加入项目资源的四张图片名称指派给数组之后就使用此数组来示范眨眼效果程序代码撰写于窗体的Load事件处理例程中如下所示
private void Blog_DemoForm
_Load(object sender
EventArgs e)
{
AssemblyInfoClass myAssembly = new AssemblyInfoClass();
thisText = myAssemblyAsmFQName;
// 指派数组成员
arrImages[] = PropertiesResourcesEye;
arrImages[] = PropertiesResourcesEye;
arrImages[] = PropertiesResourcesEye;
arrImages[] = PropertiesResourcesEye;
}
图表
如果您要使用 Visual C# 来制作「关于」对话框建议先使用Visual Studio 所提供的模板来产生关于对话框窗体然后再自订窗体所要呈现的内容(如图表所示)在此我们选择将组件的相关信息填入窗体对应的控件请于「关于」对话框窗体的 Load 事件处理例程中撰写下列程序代码
private void AboutBox_Load(object sender EventArgs e)
{
AssemblyInfoClass myAssembly = new AssemblyInfoClass();
labelProductNameText = 产品名称 + myAssemblyProduct;
labelVersionText = 版本 + myAssemblyVersion;
labelCopyrightText = 版权宣告 + myAssemblyCopyright;
labelCompanyNameText = 公司名称 + myAssemblyCompany;
textBoxDescriptionText = 细部描述 +
myAssemblyDescription;
}
要显示「关于」对话框请替「说明」菜单项目的Click事件处理例程中撰写下列程序代码
private void toolStripMenuItem
_Click(object sender
EventArgs e)
{
// 显示关于对话框
AboutBox MyAboutBox = new AboutBox();
// 设定关于对话框的启始位置
MyAboutBoxStartPosition = FormStartPositionCenterScreen;
MyAboutBoxShow();
}
当用户点选不同的选项按钮时将会执行下列程序代码来显示不同的动画效果这些程序代码撰写于选项按钮的 CheckedChanged 事件处理函式中如下所列
private void RadioButtons_CheckedChanged(object sender
EventArgs e)
{
if(optWinkChecked)
{
tmrAnimationInterval = WINK_TIMER_INTERVAL;
}
else if(optBallChecked)
{
tmrAnimationInterval = BALL_TIMER_INTERVAL;
}
else if(optTextChecked)
{
tmrAnimationInterval = TEXT_TIMER_INTERVAL;
}
OnResize(EventArgsEmpty);
}
自订函式 RadioButtons_CheckedChanged 会叫用 OnResize 函式来产生不同的图形请大家注意我们系使用 Graphics 类别的 FillEllipse 方法来绘制球形程序代码如下所列
protected override void OnResize(EventArgs ea)
{
if (optWinkChecked)
{
Graphics grfx = CreateGraphics();
// 重绘窗体
thisRefresh();
}
else if (optBallChecked)
{
Graphics grfx = CreateGraphics();
grfxClear(BackColor);
double dblRadius = MathMin(ClientSizeWidth / grfxDpiXClientSizeHeight / grfxDpiY) / intBallSize;
intBallRadiusX = (int)(dblRadius * grfxDpiX);
intBallRadiusY = (int)(dblRadius * grfxDpiY);
intBallMoveX = (int)(MathMax( intBallRadiusX / intMoveSize));
intBallMoveY = (int)(MathMax( intBallRadiusY / intMoveSize));
intBitmapWidthMargin = intBallMoveX;
intBitmapHeightMargin = intBallMoveY;
intBallBitmapWidth = * (intBallRadiusX + intBitmapWidthMargin);
intBallBitmapHeight = * (intBallRadiusY + intBitmapHeightMargin);
bitmap = new Bitmap(intBallBitmapWidth intBallBitmapHeight);
grfx = GraphicsFromImage(bitmap);
grfxClear(BackColor);
// 绘制球形
grfxFillEllipse(BrushesRed new Rectangle(intBallMoveXintBallMoveY * intBallRadiusX * intBallRadiusY));
intBallPositionX = (int)(ClientSizeWidth / );
intBallPositionY = (int)(ClientSizeHeight / );
}
else if (optTextChecked)
{
Graphics grfx = CreateGraphics();
grfxClear(BackColor);
}
}
最后利用定时器将图形连续重绘于窗体上便产生了动画效果程序代码撰写于定时器的 Tick 事件处理例程中如下所示
private void tmrAnimation_Tick(object sender
EventArgs e)
{
// 眨眼效果
if(optWinkChecked)
{
Graphics grfx = CreateGraphics();
// 将数组中之图形绘制在画面上
grfxDrawImage(arrImages[intCurrentImage](int)(
(ClientSizeWidth arrImages[intCurrentImage]Width) / )
(int)((ClientSizeHeight arrImages[intCurrentImage]Height) / )
arrImages[intCurrentImage]WidtharrImages[intCurrentImage]Height);
intCurrentImage += j;
if(intCurrentImage == )
{
j = ;
}
else if(intCurrentImage == )
{
j = ;
}
}
else if(optBallChecked) // 弹跳的球
{
Graphics grfx = CreateGraphics();
// 将球绘制在画面上
grfxDrawImage(bitmap(int)(intBallPositionX intBallBitmapWidth / )
(int)(intBallPositionY intBallBitmapHeight / )
intBallBitmapWidth intBallBitmapHeight);
// 移动球的位置
intBallPositionX += intBallMoveX;
intBallPositionY += intBallMoveY;
// 球碰到左右边界
if(intBallPositionX + intBallRadiusX >= ClientSizeWidth || intBallPositionX intBallRadiusX <= )
{
intBallMoveX = intBallMoveX;
SystemSoundsBeepPlay();
}
// 球碰到上下边界
if(intBallPositionY + intBallRadiusY >= ClientSizeHeight || intBallPositionY intBallRadiusY <= )
{
intBallMoveY = intBallMoveY;
SystemSoundsBeepPlay();
}
}
else if (optTextChecked) // 闪动文字
{
Graphics grfx = CreateGraphics();
// 设定文字的字型与大小
Font font = new Font(Microsoft Sans Serif FontStyleBold GraphicsUnitPoint);
// 设定要显示的文字
string strText = 章立民研究室;
SizeF sizfText = new SizeF(grfxMeasureString(strText font));
// X坐标与Y坐标的配对
PointF ptfTextStart = new PointF((float)(ClientSizeWidth sizfTextWidth) /
(float)(ClientSizeHeight sizfTextHeight) / );
PointF ptfGradientStart = new PointF( );
PointF ptfGradientEnd = new PointF(intCurrentGradientShift );
// 设定笔刷
LinearGradientBrush grBrush = new LinearGradientBrush(ptfGradientStart ptfGradientEnd ColorBlue BackColor);
// 将文字绘制在画面上
grfxDrawString(strText font grBrush ptfTextStart);
// 以不同的坐标绘制文字造成闪动效果
intCurrentGradientShift += intGradiantStep;
if (intCurrentGradientShift == )
{
intGradiantStep = ;
}
else if (intCurrentGradientShift == )
{
intGradiantStep = ;
}
}
}