科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Delphi控件的“拿来主义”

Delphi控件的“拿来主义”

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

一个优秀的Delphi程序员,不仅要会使用控件,还要会写控件。

作者:xm4014 来源:论坛 2007年10月31日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
----问题二及解决方案

  每一条导入表中的纪录除了ISO文件中的内容外,还需要有书的类型,期号,以及ID号,而TPgCSV在插入新纪录时只处理了同文本文件中的数据相关的字段,因此,这些字段的内容需要我们自己来加入。不用说,很自然的就会想到Table中的AfterInsert事件.但问题是,我的Table在DataModule单元中,我必须传参数到AfterInsert事件中,麻烦!同时,这样的处理会带来维护上的混乱,一个单元里面发生的事件应该尽量由这个单元里面的函数或过程来处理。于是,我又想到了在当前单元中写一个处理过程,然后在程序运行时把这个过程指派给Table的AfterInsert事件,导入结束后再禁止掉。可行,但还是麻烦!既然大多数情况下都会遇到这样的问题,那何不一了百了,把这个事件封装起来呢.

  同问题一一样,这里我们还是需要一个事件处理过程AfterInsert.这一次应该加在哪儿呢?大家肯定一眼就看出来了:

procedure TPgCSV.CSVToDataSet;
 begin
  …
  FDataset.DisableControls;
  while (not Eof(FFile)) and (not FStop) do
   begin
    //read from CSV
    Readln(FFile,RecordString);
    //xm4014's modification
    if Assigned(FRegulateString) then
     FRegulateString(self,RecordString);
     //add new record
     try
      FDataset.Append;
      //应该加在这儿!
      //xm4014's modification
      if Assigned(FAfterInsert) then
       AfterInsert(self,FDataset);
       …
      for i:=1 to CountMapItems do
       …
    end;

  同样,这里需要定义新的事件声明和事件属性,因为需要将FDataSet的参数传递出去,声明代码可参看Delphi控件的拿来主义(二)(http://www.csdn.net/develop/read_article.asp?id=11855).

  重新编译控件,就可在AfterInsert事件中添加代码对书的类型,期号,以及ID号进行赋值了.

  ----问题三及解决方案

  涉及到数据库的问题现在都已经解决了.但是还有一个显示问题.程序要求用ProgressBar显示导入进度.为了设置ProgressBar.Max的值,我需要在导入之前知道ISO文件中一共有多少条纪录,即一个类似于RecordCount的属性.但是TPgCSV中没有这样的一个属性.

  那么我们就来添加一个这样的属性

//xm4014's modification
property CSVRecordCount : integer read FCSVRecordCount write FCSVRecordCount default 0;

  怎么样给它赋值呢? 很简单,可以用ReadLn(F)对ISO文件进行扫描,然后将扫描的次数累加。

  关键是在哪儿进行这个处理.很显然,对于同一个文件,这样的工作只需要做一次就可以了。既然对于不同的文件才需要重新统计,那么我们可以在每次设置文件名属性的时候,对文本文件进行扫描。

  好,找到TPgCSV的文件名属性

property CSVFile : string read FCSVFile write FCSVFile;

  做一下小小的修改

  新的属性声明

property CSVFile : string read FCSVFile write SetCSVFile;

  按Ctrl+shift+c编写SetCSVFile的方法代码如下

procedure TPgCSV.SetFCSVFile(const Value: string);
var
 F1:TextFile;
 iCount:integer;
begin
 if FCSVFile<>Value then
 begin
  FCSVFile := Value;
  //文件名一换,就重新扫描,改变FCSVRecordCount的值
  if FileExists(Value) then
  begin
   AssignFile(F1, Value);
   Reset(F1);
   iCount:=0;
   while not Eof(F1) do
   begin
    ReadLn(F1);
    Inc(iCount);
   end;
   FCSVRecordCount:=iCount;
  end;
 end;
end;

  编译之后我们就可以在导入操作进行之前放心的调用CSVRecordCount属性获取纪录个数值了:

ProgressBar1.Min :=0;
ProgressBar1.Max:=PgCSV1.CSVRecordCount;

  以上程序在Delphi 6.0/Win98下调试通过

   写到这里基本上算是大功告成了.其实前前后后做的修改掰着指头都可以数出来.可就是这么点小小的升级,让我真正觉得用起来更加得心应手,我想,下次我再用的时候,会越发体会到它的价值.而且经过这么一番分析修改,我也长进不少啊,比半瓢多了几滴,呵呵!

  需要指出的是,TPgCSV是一个简单的控件,它既没有很复杂的关系,也不涉及到对VCL核心内容的调用,所以在修改的时候是不用有太多的顾虑的.一旦源码中涉及到很复杂的层次关系时,就需要对你添加或修改的每一行代码深思熟虑了,不然,可能会牵一发而动全身,最后想回头都难了.因此,我所说的拿来用的原则实际上还是依托于控件本身的功能,而没有实质内容上的变动。要达到随心所欲的境界,各位(我也在内)还要继续努力啊!

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章