`
mmdev
  • 浏览: 13291640 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

.Net Micro Framework研究—应用实例

 
阅读更多

试验平台:.Net Micro Framework 模拟器
在前几篇关于.Net Micro Framework的研究文章中,我对它的绘图功能实不敢恭维,不过微软的MF开发人员很聪明,对位图方面的功能实现的就比较完善,这样做起图形应用来就不至于捉襟见肘了。
前段时间用.Net Compact Framework实现了一个奥运场馆查询(相关文章请参见:http://blog.csdn.net/yefanqiu/archive/2007/11/13/1882835.aspx),现在我们用.Net Micro Framework也实现一个,看看哪一个更炫。
(效果是不是比用.Net Compact Framework做的还棒!)
我这个程序脱胎于MF的示例文件NewPresentation,不过我对它进行了大刀阔斧的改进,原程序在实现菜单时至少需要两套大小不同的图片,现在我已经修改成仅需要一套图片了,此外我对tinyfnt中文字库的创建程序又进行了优化,可以更高效、更完美的创建字库了(相关文章请参见:http://blog.csdn.net/yefanqiu/archive/2007/11/01/1862300.aspx)。
如优化前菜单添加代码:
MenuItem menuItem1 = new MenuItem(Resources.BitmapResources.Vertical_Stack_Panel_Icon_Small, Resources.BitmapResources.Vertical_Stack_Panel_Icon, "Vertical Stack Panel", Resources.BitmapResources.Canvas_Panel_Icon);
MenuItem menuItem2 = new MenuItem(Resources.BitmapResources.Horizontal_Stack_Panel_Icon_Small, Resources.BitmapResources.Horizontal_Stack_Panel_Icon, "Horizontal Stack Panel", Resources.BitmapResources.Canvas_Panel_Icon);
MenuItem menuItem3 = new MenuItem(Resources.BitmapResources.Canvas_Panel_Icon_Small, Resources.BitmapResources.Canvas_Panel_Icon, "Canvas Panel", Resources.BitmapResources.Canvas_Panel_Icon);
MenuItem menuItem4 = new MenuItem(Resources.BitmapResources.Diagonal_Panel_Icon_Small, Resources.BitmapResources.Diagonal_Panel_Icon, "Diagonal Panel", Resources.BitmapResources.Canvas_Panel_Icon);
MenuItem menuItem5 = new MenuItem(Resources.BitmapResources.Scrollable_Panel_Icon_Small, Resources.BitmapResources.Scrollable_Panel_Icon, "Scrollable Panel", Resources.BitmapResources.Canvas_Panel_Icon);
MenuItem menuItem6 = new MenuItem(Resources.BitmapResources.Free_Drawing_Panel_Icon_Small, Resources.BitmapResources.Free_Drawing_Panel_Icon, "Free Drawing Panel", Resources.BitmapResources.Canvas_Panel_Icon);
// Add each of the menu items to the menu item panel
m_MenuItemPanel.AddMenuItem(menuItem1);
m_MenuItemPanel.AddMenuItem(menuItem2);
m_MenuItemPanel.AddMenuItem(menuItem3);
m_MenuItemPanel.AddMenuItem(menuItem4);
m_MenuItemPanel.AddMenuItem(menuItem5);
m_MenuItemPanel.AddMenuItem(menuItem6);
优化后的代码:
m_MenuItemPanel.AddMenuItem(new MenuItem(Resources.BitmapResources.M1, "国家体育馆"));
m_MenuItemPanel.AddMenuItem(new MenuItem(Resources.BitmapResources.M2, "北京大学体育馆"));
m_MenuItemPanel.AddMenuItem(new MenuItem(Resources.BitmapResources.M3, "国家游泳中心-水立方"));
m_MenuItemPanel.AddMenuItem(new MenuItem(Resources.BitmapResources.M4, "国家体育场-鸟巢"));
m_MenuItemPanel.AddMenuItem(new MenuItem(Resources.BitmapResources.M5, "北京射击馆"));
m_MenuItemPanel.AddMenuItem(new MenuItem(Resources.BitmapResources.M6, "顺义奥林匹克水上公园"));
实事求是的说,MF示例实现的图形菜单动画比我在北京2008奥运场馆速查中实现的要好,它的更规范,更具有通用性。相关代码如下:
// 菜单类
internal sealed class MenuItemPanel : Control
{
private int _currentChild = 0;
private int _width;
private int _height;
private int _animationStep;
private Color ForeColor;
public ArrayList MenuItemList;
public MenuItemPanel(int width, int height, Color ForeColor,Color BackColor)
{
//背景色
Background = new SolidColorBrush(BackColor);
//前景色
this.ForeColor = ForeColor;
//大小
_width = width;
_height = height;
//菜单选项集合
MenuItemList = new ArrayList();
}
//添加菜单选项
public void AddMenuItem(MenuItem menuItem)
{
MenuItemList.Add(menuItem);
}
//当前菜单选项索引
public int CurrentChild
{
get { return _currentChild; }
set
{
if (value > _currentChild) _animationStep = maxStep; // 向右移动
else if (value < _currentChild) _animationStep = -maxStep; // 向左移动
else _animationStep = 0; // 没有移动
if (value >= MenuItemList.Count) value = 0; // 菜单项是一个环状结构
if (value < 0) value = MenuItemList.Count - 1;
//开始重绘
if (_animationStep != 0)
{
_currentChild = value;
Invalidate(); //开始移动
}
}
}
static public int maxStep = 5; //动画帧数
const int xOffsetSeparation =2; //每个菜单项的间距
const int timerInterval = 20; //移动每一个帧之间的动画时间ms
//绘制菜单
public override void OnRender(DrawingContext dc)
{
base.OnRender(dc);
//获得图片宽度
int largeX = ((MenuItem)MenuItemList[0]).ImageWidth + xOffsetSeparation;
//起始坐标
int x = (_width / 2) - ((largeX * 2) + (largeX / 2));
int y =22;
//缩放比例
int scale = 0;
//缩放比例的步长
int scaleOffset = System.Math.Abs(_animationStep);
//X方向移动
x += _animationStep * 5;
//绘背景
dc.DrawImage(Resources.GetBitmap(Resources.BitmapResources.Main), 0, 0);
#region //绘菜单图像
for (int i = _currentChild - 2; i < _currentChild + 3; i++)
{
if (i == _currentChild)//中间图像
{
scale = maxStep - scaleOffset;
}
else//两边图像
{
if ((_animationStep < 0 && i == _currentChild + 1) || (_animationStep > 0 && i == _currentChild - 1))
scale = scaleOffset;
else
scale = 0;
}
//当前菜单项
MenuItem menuItem = null;
if (i < 0)menuItem = (MenuItem)MenuItemList[MenuItemList.Count + i];
else if (i > MenuItemList.Count - 1) menuItem = (MenuItem)MenuItemList[i - MenuItemList.Count];
else menuItem = (MenuItem)MenuItemList[i];
menuItem.Render(dc, x, y, scale);
x += largeX;
}
#endregion
#region //写菜单文本
if (_width > 0)
{
int step = 20;
int row = 125;
if (_width < _height) step = 40;
//写说明
string text = ((MenuItem)MenuItemList[_currentChild]).Description;
dc.DrawText(ref text, Resources.GetFont(Resources.FontResources.china2008), ForeColor, 10, row, _width - 20, step, TextAlignment.Center, TextTrimming.None);
}
#endregion
//启动动画时钟
StartAnimationTimer();
}
private DispatcherTimer _animationTimer;
private void StartAnimationTimer()
{
if (_animationStep != 0)
{
if (_animationTimer == null)
{
_animationTimer = new DispatcherTimer(this.Dispatcher);
_animationTimer.Interval = new TimeSpan(0, 0, 0, 0, timerInterval);
//每隔一段时间触发该事件
_animationTimer.Tick += new EventHandler(OnAnimationTimer);
}
_lastTick = DateTime.Now.Ticks;
_animationTimer.Start();
}
}
long _lastTick = 0;
private void OnAnimationTimer(object o, EventArgs e)
{
_animationTimer.Stop();
long ms = ((DateTime.Now.Ticks - _lastTick) / 10000);
_lastTick = DateTime.Now.Ticks;
int increment = (int)(ms / timerInterval);
if (increment < 1) increment = 1;
else if (increment > maxStep) increment = maxStep;
if (_animationStep < 0) _animationStep += increment;
else if (_animationStep > 0) _animationStep -= increment;
//重新触发OnRender函数的执行
Invalidate();
}
//窗体可用尺寸
protected override void MeasureOverride(int availableWidth, int availableHeight, out int desiredWidth, out int desiredHeight)
{
desiredWidth = _width;
desiredHeight = _height;
}
}
// 菜单选项类
internal sealed class MenuItem : Control
{
private Bitmap _image; // 菜单图标
private string _description; // 菜单说明
private int[] _widthSteps; // 宽度步长数组
private int[] _heightSteps; // 高度步长数组
public int ImageWidth; // 图像宽度
public int ImageHeight; // 图像高度
private float fScale = (float)0.8; // 缩小因子
public int SmallWidth; // 缩小后的宽度
public int SmallHeight; // 缩小后的高度
public MenuItem()
{
}
public MenuItem(Resources.BitmapResources rBitmap, string description)
{
//菜单图像
_image = Resources.GetBitmap(rBitmap);
//图像尺寸
ImageWidth = _image.Width;
ImageHeight = _image.Height;
SmallWidth = (int)(fScale * ImageWidth);
SmallHeight = (int)(fScale * ImageHeight);
//菜单说明
_description = description;
//创建中间动画帧尺寸数组
_widthSteps = new int[MenuItemPanel.maxStep];
_heightSteps = new int[MenuItemPanel.maxStep];
//动画变化总大小
int wDiff = ImageWidth - SmallWidth;
int hDiff = SmallHeight - SmallHeight;
//保存每次变化的大小
for (int i = 1; i < MenuItemPanel.maxStep; i++)
{
_widthSteps[i] = (wDiff / MenuItemPanel.maxStep) * i;
_heightSteps[i] = (hDiff / MenuItemPanel.maxStep) * i;
}
}
//菜单说明
public string Description
{
get { return _description; }
set { _description = value; }
}
//菜单绘制
public void Render(DrawingContext dc, int x, int y, int scale)
{
// 图像必须存在
if (_image != null)
{
if (scale == MenuItemPanel.maxStep)
{
Width = ImageWidth;
Height = ImageHeight;
dc.DrawRectangle(new SolidColorBrush(Color.Black), new Pen(Color.Black), x+2, y+2, Width, Height);
dc.DrawImage(_image, x, y);
}
else
{
if (scale == 0)
{
Width = SmallWidth;
Height = SmallHeight;
x += ((ImageWidth - Width) / 2);
y += ((ImageHeight - Height) / 2);
dc.DrawRectangle(new SolidColorBrush(Color.Black), new Pen(Color.Black), x + 2, y + 2, Width, Height);
dc.Bitmap.StretchImage(x, y, _image, Width, Height, 255);
}
else
{
int wDiff = ImageWidth - SmallWidth;
int hDiff = SmallHeight - SmallHeight;
Width = SmallWidth + _widthSteps[scale];
Height = SmallHeight + _heightSteps[scale];
x += ((ImageWidth - Width) / 2);
y += ((ImageHeight - Height) / 2);
dc.DrawRectangle(new SolidColorBrush(Color.Black), new Pen(Color.Black), x + 2, y + 2, Width, Height);
dc.Bitmap.StretchImage(x, y, _image, Width, Height, 255);
}
}
}
}
}
有条件的网友可以和微软提供的示例NewPresentation对比一下看看,也许更能看出它们的异同。有时间我在把这个类封装成一个控件(基于.Net CF),这样在windows和wince平台就都能使用了。

分享到:
评论

相关推荐

    Microsoft .NET Micro Framework嵌入式编程(美 汤普逊)

    这本书旨在帮助读者理解和掌握如何在嵌入式系统中应用.NET Micro Framework进行高效开发。 .NET Micro Framework 是微软推出的一个轻量级的.NET运行时环境,专门设计用于资源受限的设备,如物联网(IoT)中的传感器、...

    GHI .NET Micro Framework培训教材(英文版)

    教材详细介绍了如何使用C#语言进行编程,并提供了丰富的实例来帮助读者理解和掌握.NET Micro Framework的核心概念和技术。 - **目标受众**:面向初学者,包括但不限于学生、业余爱好者以及希望快速入门.NET Micro ...

    Windows Embedded从入门到精通系列课程(18):.NET Micro Framework——用模拟器零成本体验MF开发

    通过学习和实践这个系列课程,你将掌握.NET Micro Framework的基本原理和应用技巧,无论你是物联网开发的新手,还是寻求在现有项目中引入.NET MF的资深开发者,都能从中获益匪浅。利用模拟器进行无成本开发,不仅...

    GHI .NET MICRO FRAMEWORK入门教程

    .NET Micro Framework将.NET平台的强大功能与Visual Studio的高效性相结合,使得开发者能够用熟悉且高效的工具来构建基于.NET的嵌入式应用。 #### 目标读者 本教程适合以下几类读者: - 对嵌入式系统感兴趣的学生...

    Vecc.Netduino.Drivers.Tmp102Sensor:.NET Micro Framework 的 Tmp102 传感器驱动程序

    在使用该驱动程序时,开发者首先需要了解.NET Micro Framework,这是一个轻量级的.NET运行时,专门为资源有限的嵌入式设备设计。通过.NET Micro Framework,开发者可以使用C#或VB.NET编写代码,实现对硬件的直接控制...

    netmf-azure-mobile-services:用于从 .NET Micro Framework 与 Azure 移动服务通信的类库

    要求Microsoft .NET Micro Framework 4.2 或更高版本依赖关系这个库依赖于 Json.NetMF ( ),所以归功于这个库示例用法您必须使用构造函数实例化类,并至少提供移动服务的 URL。 第二个和第三个参数是通过 Internet ...

    netmfazureservicebus:用于与 Azure 服务(队列、主题和事件中心)通信的 .NET Micro Framework 库

    网络故障服务总线用于与 Azure 服务(队列、主题和事件中心)通信的 .NET Micro Framework 库学分我从以下位置获得了 SAS 令牌生成器: : 非常感谢您的出色工作.要求.NET 微框架 4.3 视觉工作室用于创建服务总线命名...

    手持设备环境的搭建及程序开发,如手持终端设备、PDA手持终端、条码数据采集器等设备.zip

    .NET Micro Framework 是一个适用于小型设备的.NET框架,它允许开发者使用C#和Visual Basic .NET来编写应用程序,目标是资源有限的嵌入式设备,如手持终端。它包括类库、运行时环境和开发工具。 3. **Windows CE**...

    .Net MF 模拟器

    .NET Micro Framework(简称.NET MF)是由微软开发的一个嵌入式操作系统平台,主要针对资源有限的设备,如物联网(IoT)设备、智能家居组件和小型工业控制器。标题中的".Net MF 模拟器"指的是一个用于模拟.NET MF环境...

    MINI2440 WINCE6 LED测试程序

    总结来说,MINI2440开发板上的WINCE6.0 LED测试程序是一个典型的嵌入式系统应用实例,它展示了如何利用C#编程语言与.NET Micro Framework来控制硬件资源。通过理解GPIO的工作原理,结合C#的API调用,开发者可以灵活...

    InTheHand.Net.Personal.zip

    该库适用于Windows桌面应用程序、Windows Phone以及.NET Micro Framework等多种平台。 在使用`InTheHand.Net.Personal.dll`之前,需要确保你的项目引用了这个库。在Visual Studio中,可以通过右键点击项目,选择...

    C#开发Android应用实战-使用Mono for Android和.NET C#(PDF中文扫描版下载,吾乐吧软件站分享)

    这个框架的核心是.NET Micro Framework和Mono运行时,它将.NET Framework的关键部分移植到了Android平台,使得开发者可以充分利用.NET的强大功能,同时享受到跨平台开发的便利。 本书的核心内容可能包括以下几个...

    ASP.NET-[博客空间]mBlog个人博客系统v1.0Beta2.zip

    这个系统可能包含了数据库交互、用户认证、权限管理、内容发布、评论功能等一系列Web应用的基本元素,是学习和研究ASP.NET Web应用程序开发的一个实例。 【mBlog个人博客系统】 mBlog个人博客系统可能是一个开源或...

    WINDOWS CE.NET (WINCE)下电量读取函数VB.NET

    VB.NET是.NET Micro Framework下的编程语言,可以用来创建这类功能。本篇文章将深入探讨如何在Windows CE环境下使用VB.NET来实现电量读取。 首先,Windows CE操作系统提供了电源管理接口,通过这个接口,开发者可以...

    pwm_example_v1.rar_in

    Fez Domino是一款基于.NET Micro Framework的开发平台,它提供了丰富的硬件接口,包括PWM输出,便于开发者进行嵌入式系统开发。 Fez Domino板载的PWM功能主要由微控制器的硬件定时器支持。在C#中,我们可以通过.NET...

    M2Mqtt.NetCF39.dll_mqtt_

    这个框架主要针对Windows CE、Windows Mobile和.NET Micro Framework等资源有限的环境。M2Mqtt.NetCF39.dll是专为这些平台设计的版本,它使得在这些平台上实现MQTT协议变得容易且高效。 MQTT协议的核心特点是其简单...

    at2051中实现AD转换的源代码!也算是一个实例程序.zip

    C#通常用于编写桌面应用程序、Web应用或服务器端逻辑,但它也可以用于嵌入式系统,尤其是当系统运行.NET Micro Framework或者使用支持C#的实时操作系统时。在这样的环境中,C#可以访问硬件资源,如微控制器的ADC。 ...

Global site tag (gtag.js) - Google Analytics