Delphi 制作自定义数据感知控件并装入包(dpk文件)中(与DBText类似的数据感知控件)
一、基础知识简介:
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类似的数据感知控件)的更多相关文章
- 如何用Apache POI操作Excel文件-----如何在已有的Excel文件中插入一行新的数据?
在POI的第一节入门中,我们提供了两个简单的例子,一个是如何用Apache POI新建一个工作薄,另外一个例子是,如果用Apache POI新建一个工作表.那么在这个章节里面,我将会给大家演示一下,如 ...
- 使用Apache POI操作Excel文件---在已有的Excel文件中插入一行新的数据
package org.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...
- 从文件中读取yuv和h264数据
1.从文件中读取h264数据 参考ffmpeg avc.c写的从文件中一帧帧读取h.264数据的demo #include <stdio.h> #include <stdlib.h& ...
- linux下向一个文件中的某行插入数据的做法
sed -i 'ni\x' test.file 表示向test.file文件里的第n行的前面添加x内容sed -i 'na\x' test.file 表示向test.file ...
- 使用jmeter往指定文件中插入一定数量的数据
有一个需求,新建一批账号,把获取的账号相关信息存入文本文件,当文本文件保存的数据达到一定的数量,就自动停止新建账号. 分析下需求: 1.把账号信息保存到文件,需要使用bean shell脚本(bean ...
- java web 通过前台输入的数据(name-value)保存到后台 xml文件中
一:项目需求,前端有一个页面,页面中可以手动输入一些参数数据,通过点击前端的按钮,使输入的数据保存到后台生成的.xml文件中 二:我在前端使用的是easyui的propertygrid,这个能通过da ...
- 使用jmeter往指定文件中插入一定数量的数据(转)
有一个需求,新建一批账号,把获取的账号相关信息存入文本文件,当文本文件保存的数据达到一定的数量,就自动停止新建账号. 分析下需求: 1.把账号信息保存到文件,需要使用bean shell脚本(bean ...
- Jmeter beanshell把数据写入csv文件中,最后清除csv数据
有时候我们需要使用jmeter去结合csv文件去做一些简单的数据驱动处理: 例如把数据库数据黏贴到csv文件中或者把网页上的数据填入到csv文件中: 直接我一般是用手自己黏贴复制过csv文件中,比较麻 ...
- Elasticsearch准实时索引实现(数据写入到es分片并存储到文件中的过程)
溢写到文件系统缓存 当数据写入到ES分片时,会首先写入到内存中,然后通过内存的buffer生成一个segment,并刷到文件系统缓存中,数据可以被检索(注意不是直接刷到磁盘) ES中默认1秒,refr ...
随机推荐
- 4-c++教程起航篇-学习笔记
c++教程起航篇 我们会讲C++那些事,C++与C语言的关系. C++诞生于贝尔实验室. C++之父: 本贾尼·斯特劳斯特卢普 C++社区排行榜 最新排行,c++排名第三,Python排名第四 C++ ...
- C语言程序设计:现代方法(第2版)第二章全部习题答案
前言 本人在通过<C语言程序设计:现代方法(第2版)>自学C语言时,发现国内并没有该书完整的课后习题答案,所以就想把自己在学习过程中所做出的答案分享出来,以供大家参考.这些答案是本人自己解 ...
- Android Studio 引入 Git 并提交代码
File -> Settings -> Version Control -> Git -> Path to Git executable -> 选择本地 Git 可执行文 ...
- 前端chrome调试技巧
待更新:http://blog.csdn.net/xueer767/article/details/65936204?locationNum=8&fps=1
- 微信小程序学习笔记(1)-微信小程序样式设置逻辑
1.微信小程序的样式设置统一在每一页的.wxss的样式文件中,所有的样式设置代码统一写入这个文件中: 2.样式主要是通过.wxml里面控件的“class”属性来调用,此处调用会有几个细节要注意: 1) ...
- Qt-第一个QML程序-3-自定义一个按钮
项目基本信息前两个已经说了,这里直接放下运行截图, 对的,这里就是说上面的那个红色的按钮,这里需要了解Qml的动画和状态 这里先把整个按钮的代码写出来,一点一点写 Rectangle { id:clo ...
- 孤荷凌寒自学python第八十六天对selenium模块进行较详细的了解
孤荷凌寒自学python第八十六天对selenium模块进行较详细的了解 (今天由于文中所阐述的原因没有进行屏幕录屏,见谅) 为了能够使用selenium模块进行真正的操作,今天主要大范围搜索资料进行 ...
- kaldi - Online Audio Server(服务器客户端建立方法-旧版在线解码)
目录 一.服务器客户端识别系统建立方法 1. Command line to start the server(服务器端启动方式): 2. Command line to start the clie ...
- Java抽象与接口的区别
Java抽象与接口的区别 答案方式一.简单来说,1.接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的, 2.另外,实现接口的一定要实现接口里定义的所有 ...
- Thunder团队第一周 - Scrum会议4
Scrum会议4 小组名称:Thunder 项目名称:爱阅app Scrum Master:代秋彤 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传 ...