一、基础知识简介:

1、包的命名介绍:

包的命名没有规则,但是建议遵守包的命名约定:包的命名与包的版本相关,包的名称前面几个字符通常表示作者或公司名,也可以是控件的一个描述词,后面紧跟的Std表示运行期包,Dsgn表示设计期包,然后是版本号。如:MyDataEditStd60,MyDataEditDsgn60。

2、对象浏览器【Object Inspector】中一个属性感知一类控件的原理:

控件属性的感知只不过是将它的一个属性声明为将要感知的控件类而已,例如要感知Image控件,则:property MyImage:TImage read GetImage write SetImage;这样之后,窗体中的所有的TImage类型的控件,它都能感知到。

 

3、数据感知控件与其他相关控件进行交互的方法:

数据感知控件通过DataLink对象与DataSource进行交互,所以为控件增加数据感知能力需要创建一个TDataLink(或其派生类)对象作为控件的成员,并为控件创建公开的DataField和DataSource属性;然后需响应TDataLink对象的OnDataChange和OnUpdateData事件。

我们用到了一个重要的类TFieldDataLink。它是控件内部的数据联接对象,从TDataLink继承下来,它的作用是与TDataSource组件相互通信,连接单个字段进行数据提取。我们将要处理这个对象的OnDataChange事件,这样,当字段或记录有所改变时就会得到通知,进行相应的数据处理。

4、当其中一个控件被删除或者断开时,通知其他控件的通知函数:

感知组件需要和DataSource数据源控件和DataSet数据集控件相组合才能实现数据库数据的读写,那么当删除其中一个时,如果其他两个控件不知道,就会出现异常,甚至导致死机。那么我们怎样才能做到通知其他组件呢?Value.FreeNotification(Self)就是做这个工作的!FreeNotification(self)将会把我们的组件置入其通知对象列表中,被撤消时,它会依次调用通知对象列表中所有对象的Notification方法。每个数据控件都有一个Notification方法,当某一控件从窗体上移走时,DELPHI的IDE调用该方法通知其它控件。

二、制作数据感知控件的具体步骤:

本文以制作一个类似于DBEdit的控件为例。

1、 创建组件,并安装在新包中。

1>、首先使用组件向导从TEdit(StdCtrls)下继承下来,命名TMyDataBaseEdit,单元名为MyDataBaseEdit.pas,

2>、安装在一个新的包文件中,起名为MyDataEditStd60.Dpk。 (此种不需要dpr工程)

(【Delphi 编写Pas文件类型的组件】 中的 【二、制作一个简单的组件基本步骤】 有介绍)

2、 添加属性。

1>、声明一个内部数据连接对象:TfieldDataLink,用于与TDataSource进行通信。

在Private中添加代码:  FDataLink: TFieldDataLink; // Uses DBCtrls;

2>、添加数据源感知属性:DataSource 和字段感知属性:DataField ;其值就显示Text中,处理事件是DataChange

和UpdateData。

只需在Pubished域添加以下代码:

property DataSource: TDataSource read GetDataSource write SetDataSource;// Uses DB:

property DataField: string read GetDataField write SetDataField;

3>、按下【shift +ctrl+ C】组合键完成属性的自动结构化功能,

private域自动添加四个函数:

procedure SetDataSource(const Value: TDataSource);

function GetDataSource: TDataSource;

procedure SetDataField(const Value: string);

function GetDataField: string;

4>、上面四个函数的实现方法:

function TMyDataBaseEdit.GetDataSource: TDataSource;

begin

Result := FDataLink.DataSource;

end;

procedure TMyDataBaseEdit.SetDataSource(const Value: TDataSource);

begin

if not(FDataLink.DataSourceFixed and (csLoading in ComponentState)) then

begin

FDataLink.DataSource := Value;

end;

if Value <> nil then

begin

// 将会把我们的组件置入其通知对象列表中,被撤消时,它会依次调用通知对象列表

// 中所有对象的Notification方法,

Value.FreeNotification(Self);

end;

end;

function TMyDataBaseEdit.GetDataField: string;

begin

Result := FDataLink.FieldName;

end;

procedure TMyDataBaseEdit.SetDataField(const Value: string);

begin

FDataLink.FieldName := value;

end;

3、 添加方法:

1>、实现通知函数(必须的)。

当某一控件从窗体上移走时,DELPHI的IDE调用该方法通知其它控件。这样,当关联的参考控件被删除时,控件就会得到消息,来处理事件,防止异常的发生,否则将会导致Delphi开发环境的不稳定甚至死机。

在protected中添加代码:

procedure Notification(AComponent: TComponent;Operation: TOperation);override;

添加实现的代码:

procedure TMyDataBaseEdit.Notification(AComponent: TComponent; Operation: TOperation);

begin

inherited Notification(AComponent, Operation);

// 当与控件相连的TdataSource控件被删除时将控件的DataSource属性置为空

if (Operation = opRemove) and (FDataLink <> nil) and (AComponent = DataSource) then

DataSource := nil;

end;

2>、实现数据处理过程

当DataSet的记录改变(如在DBGrid中滑动滚轮的浏览记录)时触发OnDataChange事件,DataChange作为该事件的事件处理句柄。

在Private中添加代码:

procedure DataChange(Sender: TObject);

添加实现的代码:

procedure TMyDataBaseEdit.DataChange(Sender: TObject);

begin

//若控件连接了的DataSet,则数据集变动时控件显示当前记录的相应字段值

if FDataLink.Field <> nil then

begin

Text := FDataLink.Field.Text;

end;

end;

3>、实现数据更新过程:

更新DataSet前将触发OnUpdateData事件,UpdateData将作为该事件的事件处理句柄;

在Private中添加代码:

procedure UpdateData(Sender: TObject);

添加实现的代码:

procedure TMyDataBaseEdit.UpdateData(Sender: TObject);

begin

// 用控件中的Text更新到相应的字段

FDataLink.Field.Text := Text;

end;

4>、实现控件失去焦点时的消息处理函数:

当控件失去焦点时触发CM_EXIT消息

在private中添加代码:

procedure CMExit(var Message: TCMExit);Message CM_Exit;

添加实现的代码:

procedure TMyDataBaseEdit.CMExit(var Message: TCMExit);

begin

try

// 控件失去焦点时更新DataSet,这将触发OnUpdateData事件

FDataLink.UpdateRecord;

except

setFocus;

//这里是将发生的异常显现出来。因为用了try except end后就不会显示出异常和错误。

raise;

end;

DoExit;

end;

5>、重新编写构造函数:

在构造函数中创建DataLink对象,连接OnDataChange、OnUpdateData事件处理句柄。

在public中添加代码:

constructor Create(AOwner: TComponent);Override;

添加实现的代码:

constructor TMyDataBaseEdit.Create(AOwner: TComponent);

begin

inherited Create(AOwner);  //必须加上这句话;

//创建DataLink对象,连接OnDataChange、OnUpdateData事件处理句柄

FDataLink := TFieldDataLink.Create;

FDataLink.OnDataChange := DataChange;

FDataLink.OnUpdateData := UpdateData;

end;

6>、重新编写析构函数:

在析构函数中销毁DataLink对象,并释放对OnDataChange、OnUpdateData事件的连接。确保使用完之后销毁FDataLink的实例,释放空间,无论是写组件还是写程序我们都要严格注意声明的对象,一定要在使用完之后释放!

在public中添加代码:

destructor Destroy;override;

添加实现的代码:

destructor TMyDataBaseEdit.Destroy;

begin

FDataLink.OnDataChange := nil;

FDataLink.OnUpdateData := nil;

FreeAndNil(FDataLink);

Inherited ;

end;

三、DPK文件类型(包)的调试

1、在创建新包dpk或者选择已经存在的包之后,点击【Ok】之后会出现安装【dpk文件对话框】,按其中的【Compile】就可以检查你编写的代码是否存在错误,但不能检测逻辑错误。

2、【Project】—>【Build XXX】也能检测代码中的错误。但是直接打开Pas文件,这个按钮不可用。可以先点击打开其所在的dpk,然后打开pas文件, 但不能检测逻辑错误.

3、安装完自定义控件后,在自定义控件的Pas中修改代码,会直接影响到调用他的程序中,所以可以直接在自定义控件的Pas文件中设置断点,进入调试, 可以检测逻辑错误;

4、在自定义控件的Pas文件中,添加的新属性、事件。在应用程序中能通过代码直接调用,但是在对象监控器【Object Inspector】中不会显示,只能重新加载自定义控件,才能显示。

四、安装dpk文件类型的组件:

第一种方法:

1、【File】-> 【Open Project】命令,然后在对话框中选择文件类型为【*.dpk;*.dpkw】的文件;

2、然后【打开】,会出现【dpk文件对话框】,点击【Compile】—>【Install】,进行安装.。

第二种方法:

1、直接在dpk文件上双击,就会出现【dpk文件对话框】,点击【Compile】—>【Install】,进行安装.。

五、删除控件:

1、【Component】—>【Install Packages】,出现一个对话框。

2、然后在【Designs Packages】 中找到当前包相对应的同名bpl文件。

3、然后【Edit】->【Yes】,打开【dpk文件对话框】,然后选择对应的文件,点击【Remove】删除。

然后再编译安装。

(也可以直接找到相应的DPK文件,双击进入【dpk文件对话框】,一般默认在lib下)

查看组件所属的包:

在【组件面板】上相应的组件上【右击】—>【Properties】,然后打开对话框,可以在【Palette】中,右侧栏中看【Components】中看到name,和它所处的包。

Delphi 制作自定义数据感知控件并装入包(dpk文件)中(与DBText类似的数据感知控件)的更多相关文章

  1. 如何用Apache POI操作Excel文件-----如何在已有的Excel文件中插入一行新的数据?

    在POI的第一节入门中,我们提供了两个简单的例子,一个是如何用Apache POI新建一个工作薄,另外一个例子是,如果用Apache POI新建一个工作表.那么在这个章节里面,我将会给大家演示一下,如 ...

  2. 使用Apache POI操作Excel文件---在已有的Excel文件中插入一行新的数据

    package org.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...

  3. 从文件中读取yuv和h264数据

    1.从文件中读取h264数据 参考ffmpeg avc.c写的从文件中一帧帧读取h.264数据的demo #include <stdio.h> #include <stdlib.h& ...

  4. linux下向一个文件中的某行插入数据的做法

    sed -i 'ni\x' test.file        表示向test.file文件里的第n行的前面添加x内容sed -i 'na\x' test.file       表示向test.file ...

  5. 使用jmeter往指定文件中插入一定数量的数据

    有一个需求,新建一批账号,把获取的账号相关信息存入文本文件,当文本文件保存的数据达到一定的数量,就自动停止新建账号. 分析下需求: 1.把账号信息保存到文件,需要使用bean shell脚本(bean ...

  6. java web 通过前台输入的数据(name-value)保存到后台 xml文件中

    一:项目需求,前端有一个页面,页面中可以手动输入一些参数数据,通过点击前端的按钮,使输入的数据保存到后台生成的.xml文件中 二:我在前端使用的是easyui的propertygrid,这个能通过da ...

  7. 使用jmeter往指定文件中插入一定数量的数据(转)

    有一个需求,新建一批账号,把获取的账号相关信息存入文本文件,当文本文件保存的数据达到一定的数量,就自动停止新建账号. 分析下需求: 1.把账号信息保存到文件,需要使用bean shell脚本(bean ...

  8. Jmeter beanshell把数据写入csv文件中,最后清除csv数据

    有时候我们需要使用jmeter去结合csv文件去做一些简单的数据驱动处理: 例如把数据库数据黏贴到csv文件中或者把网页上的数据填入到csv文件中: 直接我一般是用手自己黏贴复制过csv文件中,比较麻 ...

  9. Elasticsearch准实时索引实现(数据写入到es分片并存储到文件中的过程)

    溢写到文件系统缓存 当数据写入到ES分片时,会首先写入到内存中,然后通过内存的buffer生成一个segment,并刷到文件系统缓存中,数据可以被检索(注意不是直接刷到磁盘) ES中默认1秒,refr ...

随机推荐

  1. 利用谷歌翻译网站和Adobe Acrobat翻译英文文档,且鼠标放置后显示英文原文(无字数限制)(18/12/11更新)

    软件:Adobe Acrobat 网页:https://translate.google.cn/?tr=f&hl=zh-CN 方法:       第一步:用Adobe Acrobat 打开英文 ...

  2. 位域 (Bit field)

    最近开始看编程之美这本书,里面有一道关于中国象棋将帅位置的简单问题,如下图所示,写一个程序输出将.帅的合法位置. 分析与解法 问题的本身并不复杂,只要把所有A.B 互相排斥的条件列举出来就可以完成本题 ...

  3. VS2015 opencv 无法打开文件“opencv_calib3d330d.lib”

    我用的opencv是3.3.0,vs是2015版,找到项目的属性管理器,链接器——>输入——>附加依赖项 把其他的东西都删掉,只添加 opencv_world330d.lib;%(Addi ...

  4. TensorFlow:在PyCharm中配置TensorFlow

    在本地配置好TensorFlow后,如何在PyCharm中配置TensorFlow呢? 只需将当前的Python编译环境配置为TensFlow安装路径中的Pyhton环境,具体操作如下: 1. 打开‘ ...

  5. Android stado 运行项目,apk does not exist on disk.

    报错如下: 03/12 21:38:56: Launching iReader The APK file F:\git\iReader_nubia\iReader\build\outputs\apk\ ...

  6. mongoDB在java上面的应用

    1.实际应用过程中肯定不会直接通过Linux的方式来连接和使用数据库,而是通过其他驱动的方式来使用mongoDB 2.本教程只针对于Java来做操作,主要是模拟mongoDB数据库在开发过程中的应用 ...

  7. linux进程的学习笔记(未完)

    1. 进程是程序执行的一个实例,如果16个用户同时运行vi,那么有16个独立的进程,尽管它们共享同一个可执行代码,问题在于FreeRTOS这种系统,是否可以建2个相同的任务,需要注意什么?在linux ...

  8. Servlet的5种方式实现表单提交(注册小功能)

    Servlet的5种方式实现表单提交(注册小功能),后台获取表单数据   用servlet实现一个注册的小功能 ,后台获取数据. 注册页面: 注册页面代码 : <!DOCTYPE html> ...

  9. 欧陆词典PEST2词库

    欧陆词典PEST2单词列表,其中大概1900+单词,可能有少数几个没有录入,但不影响使用!

  10. OSG的组成结构

    OSG的组成结构 核心结构 OSG的功能类采用“命名空间+类名称”的形式来命名.命名空间的命名方式为:第一个单词小写,后继单词的首字母大写,例如osg.osgUtil.osgViewer等:类的名称则 ...