Compact Framework项目管理器
一个真实的用例,展示如何存储和检索 XML 文件,并通过红外端口进行传输。
引言
此应用程序旨在帮助项目经理跟踪各种不相关的项目。我想将项目存储在 XML 文件中,以便可以将其导入其他软件。对于编写 .NET Compact Framework 软件的人来说,有两个代码部分可能很有趣。这两个部分是 XML 存储/检索以及此应用程序中内置的 IRDA 支持。
我目前正在开发该软件的 PC 版本,该版本允许我更新我的同步目录中的项目文件。从任何一端保存信息后,ActiveSync 都会更新“我的文档”目录中的相应文件。然后我可以重新加载文件并继续工作。这是一种通过 ActiveSync 保持两个项目管理器同步的廉价方法。如果能编写 ActiveSync 服务提供商就更好了,但这需要我目前没有的时间。
背景
我曾使用 Microsoft Project 在同一个 mpp 文件中跟踪许多项目。但以这种方式使用 Microsoft Project 效果不佳。Microsoft Project 似乎非常适合建造像航天飞机这样的东西,但我需要一个工具来帮助我跟踪多个工程师的多个项目。每个工程师可能同时负责两到三个项目,我们需要跟踪他们在不同开发阶段的项目。在与负责项目的工程师交谈时做笔记,并将其输入我的 Pocket PC,这也很有用。这样,在我向上级汇报时,就可以查看这些笔记,给人一种我真正控制了部门的印象。
使用代码
在解决编写项目组织软件的问题时,我发现我需要几个不同的类。我创建了以下类来逻辑地组织项目。
Project - 主项目包含一个笔记列表、客户信息、任务列表、待办事项列表以及许多其他小信息,如目标日期、销售订单号和工程请求号。有一个 ProjectComparer
类,它将根据项目名称以升序或降序对项目列表进行排序。
Note - Note 是一个带有 DateTime
的字符串。项目有一个与该项目关联的 Note 列表。有一个 NoteComparer
类,它将按日期顺序对 Note 进行排序。创建此类的目的是为了让主屏幕的底部字段可以显示描述,然后按从最早到最晚的顺序显示所有 Note。
Customer - Customer 类包含客户信息、公司名称、电话号码和联系信息。
Task - Task 是要完成的杂项工作。它们可以链接到其他任务,可能有关联的持续时间和开始日期。将来,此项目管理器可以为每个项目配备甘特图。
ToDo - 这类似于 Task,但只有一个完成标志和一个目标日期。
还有一个类 FileIO
,它存储在 FileIO.cs 文件中。需要一些代码来保存和恢复文件,以及通过红外端口传输文件。我想将此代码与用户界面分开,因此我创建了 FileIO
对象。保存 XML 文件就像调用 SaveFile()
一样简单。同样,您可以通过调用 LoadFile()
例程来加载文件,这会在程序启动时以及在“重新加载”菜单单击时调用。加载代码如下。我删除了所有项目,加载文件,然后重新排序项目。ReSort
例程还会使项目列表框失效,以便重新绘制。
myProjects.RemoveRange( 0, myProjects.Count );
(new FileIO()).LoadFile("\\My Documents\\Projects.xml", myProjects);
listOfProjectsReSort();
在保存文件时,我将一些数据作为项目中各个项目的属性进行写入,并为项目中的所有其他列表写入带有属性的元素。
// write out the project information
fileWriter.WriteStartElement("Project");
fileWriter.WriteAttributeString("Name", p.Name );
fileWriter.WriteAttributeString("Description", p.Description );
fileWriter.WriteAttributeString("DueDate", p.DueDate );
fileWriter.WriteAttributeString("Manager", p.Resource );
...
// write out the list of tasks.
fileWriter.WriteStartElement("Tasks");
foreach( task t in p.Tasks )
{
fileWriter.WriteStartElement("Task");
fileWriter.WriteAttributeString( "Name", t.Name);
fileWriter.WriteAttributeString( "Resource", t.Resource);
fileWriter.WriteAttributeString( "PrevTask", t.PrevTask);
fileWriter.WriteEndElement();
}
...
解析这些信息也很简单。我使用一系列嵌套的 case 语句将信息放入相应的字段。通过这样设置代码,XML 文件不必按任何顺序排列,并且任何缺失的属性都会被忽略。您会注意到此代码中没有多少错误检查,在缺失重要信息方面还有改进的空间。例如,如果缺少项目名称,我真的不确定会发生什么。
XmlDocument xmlDoc = new XmlDocument();
XmlTextReader reader = new XmlTextReader( fileToReadFrom);
try
{
xmlDoc.Load( reader );
XmlNode rootElement = xmlDoc.DocumentElement;
XmlNodeList xNodes = rootElement.ChildNodes;
foreach( XmlNode childNode in xNodes )
{
project pr = new project();
foreach( XmlAttribute attrib in childNode.Attributes )
{
switch ( attrib.Name )
{
case "Name" :
pr.Name = attrib.Value;
break;
case "Description" :
pr.Description = attrib.Value;
break;
...
}
}
foreach( XmlNode child in childNode.ChildNodes )
{
switch ( child.Name )
{
case "Customer" :
foreach( XmlAttribute attrib in child.Attributes )
{
switch ( attrib.Name )
{
case "Name" :
pr.Customer.Name = attrib.Value;
break;
case "Contact" :
pr.Customer.Contact = attrib.Value;
break;
...
CF Project Manager 还可以通过弹出菜单将特定项目通过红外端口发送到另一个 pocket PC。我想能够发送多个项目(当前实现不允许)并在调试期间查看发生了什么。为了实现这些目标,我实际上将一个临时 XML 文件保存到根目录,其中包含要发送的项目。然后我使用 SendFileToIR()
将文件发送给接收器。在我当前的实现中,这个文件只包含一个项目。您也可以使用 pocket PC 内置的记事本应用程序查看此文件。
// find the appropriate project
foreach ( project p in myProjects )
{
if ( p.Name == listOfProjects.SelectedItem.ToString() )
{
ArrayList al = new ArrayList(1);
al.Add( p );
// create a file with a single record
fio.SaveFile("\\tmpIRPrjs.txt", al);
break;
}
}
// send the file
fio.SendFileToIR("\\tmpIRPrjs.txt");
在程序启动时,我启动另一个线程来运行接收器代码。接收器线程在 FileIO
类中。它是 SrvRoutine()
。只要 FileIO.isRunning
变量设置为 true,此线程就会运行。它使用 IrDAListener
类来监视红外端口,以查找传入的文件。
// variable to set running to true
fio.isRunning = true;
// create and start the thread
this.thServ = new Thread (new ThreadStart(fio.SrvRoutine));
this.thServ.Start();
在关机时,您必须确保将 isRunning
变量设置为 false,以便线程能够终止。请参见下面的代码。
fio.isRunning = false;
Thread.Sleep(550);
关注点
比较器 - Compact Framework 的列表框存在一些限制。这些列表框不会以任何方式进行排序。我必须利用 Comparer 类在每次修改列表时进行排序,以使列表框按字母顺序排序。这些 Comparer 位于 NoteComparer.cs 文件和 ProjectComparer.cs 文件中。
我使用了一些来自 Microsoft IRSquirtCF 示例的代码。以下是示例代码的链接:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/win_ce/htm/pwc_theirsquirtcfexample.asp
历史
- v1.0 版本已发布,用于本次文章提交。