当前位置: 首页 > 学习 > 电脑学习 > 程序设计 > Delphi > 基础教程 > 正文

Delphi自定义部件开发(六)

http://www.zk168.com.cn  招考学习网 2006-4-7 9:38:41
-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--

19.3 Delphi部件编程实例

 

19.3.1 创建数据库相关的日历控制-TDBCalendar

 

  当处理数据库联接时,将控制和数据直接相联是很重要的。就是说,应用程序可以建立控制与数据库之间的链。Delphi包括了数据相关的标签、编辑框、列表框和栅格。用户可以使自己的控制与数据相关。

  数据相关有若干等级。最简单的是只读数据相关或数据浏览,以及反映数据库当前状态的能力。比较复杂的是数据相关的编辑,也即用户可以在控制上操作数据库中的数据。

  在本部分中将示例最简单的情况,即创建联接数据库的单个字段的只读控制。本例中将使用Component Palette的Samples页中的TCalendar部件。

创建数据相关的日历控制包括下列几步:

● 创建和注册部件

● 使控制只读

● 增加数据联接(DataLink)

● 响应数据改变

 

19.3.1. 1创建和注册部件

 

每个部件的创建都从相同的方式开始,在本例中将遵循下列过程:

● 将部件库单元命名为DBCal

● 从TCalendar继承一个新部件,名为TDBCalendar

● 在ComponentPalette的Samples页中注册TDBCalendar

 

下面就是创建的代码:

 

unit DBCal;

 

interface

 

uses SysUtils, WinTypes, WinProc, Messages, Classes, Graphics, Controls,

Forms, Grids, Calendar;

type

TDBCalendar=class(TCalendar)

end;

 

procedure Register;

 

implementation

 

procedure Register;

begin

RegisterComponents(Samples,[TDBabendar]);

end;

 

end.

 

19.3.1.2 使控制只读

 

因为这个数据日历以只读方式响应数据,所以用户不能在控制中改变数据并指望它们反映到数据库中。

使日历只读包含下列两步:

● 增加只读属性

● 允许所需的更新

 

1. 增加只读属性

给日历控制增加只读选项是直接过程。通过增加属性,可以提供在设计时使控制只读的方法,当属性值被设为True,将使控制中所有元素不可被选。

⑴ 增加属性声明和保存值的private域:

 

type

TDBCalendar=class(TClendar)

private

FReadOnly: Boolean;

public

constructor Create (Aowner: TComponent); override;

published

property ReadOnly: Boolean read FReadOnly write FReadOnly default True;

end;

 

constructor TDBCalendar.Create(Aowner: TComponent);

begin

inherited Create(AOwner);

FReadOnly := True;

end;

 

⑵ 覆盖SelectCell方法,使得当控制是只读时,不允许选择:

 

function TDBCalendar.SelectCell(ACol, Arow: Longint): Boolean;

begin

if FReadOnly then

Result := False

else

Result := inherited SelectCell(Acol,ARow);

end;

 

还要在TDBcalendar的声明中声明SelectCell。

如果现在将Calendar加入窗体,会发现部件完全忽略鼠标和击键事件,而且当改变日期时,也不能改变选择的位置。下面将使控制响应更新。

2. 允许所需的更新

只读日历使用SelectCell方法实现各种改变,包括设置Row和Col的值。当日期改变时,UpdateCalendar方法设置Row和Col的值,但因为SelectCell不允许你改变,即使日期改变了,选择仍留在原处。

可以给日历增加一个Boolean标志,当标志为True时允许改变:

 

type

TDBCalendar=class(TCalendar)

private

Fupdating: Boolean;

protected

function SelectCell(Acol, Arow: Longint); Boolean; override;

public

procedure UpdateCalendar; override;

end;

 

function TDBCalendar.SelectCell(ACol, ARow: Longint): Boolean;

begin

if (not FUpdating) and FReadOnly then

Result := False { 如果更新则允许选择 }

else

Result := inherited SelectCell(ACol, ARow); { 否则调用继承的方法 }

end;

 

procedure UpdateCalendar;

begin

FUpdating := True; { 将标志设为允许更新 }

try

inherited UpdateCalendar; { 象通常一样更新 }

finally

FUpdating := False; { 总是清除标志 }

end;

end;

 

  现在日历仍旧不允许用户修改,但当改变日期属性时能正确反映改变;目前已有了一个真正只读控制,下一步是增加数据浏览能力。

 

  3. 增加数据联接

  控制和数据库的联接是由一个名为DataLink的对象处理。Delphi提供了几种类型的Datalink。将控制与数据库单个域相联的DataLink对象是TFieldDatalink。Delphi也提供了与整个表相联的DataLink。

  一个数据相关控制拥有DataLink对象,就是说,控制负责创建和析构DataLink。

  要建立作为拥有对象的Datalink,要执行下列三步:

  ● 声明对象域

  ● 声明访问属性

  ● 初始化DataLink

 

  ⑴ 声明对象域

  每个部件要为其拥有对象声明一个对象域。因此,日历对象DataLink 声明TFieldDataLink类型的域。

  日历部件中DataLink的声明如下:

 

type

TDBCalendar = class(TSampleCalendar)

private

FDataLink: TFieldDataLink;

end;

 

  ⑵ 声明访问属性

  每一个数据相关控制有一个DataSource属性,该属性描述应用程序给控制提供数据的数据源。而且,访问单个域的数据库还需要一个DataField 属性描述数据源中的域。

  下面是DataSource和DataField的声明和它们的实现方法:

 

type

TDBCalendar = class(TSampleCalendar)

private { 属性的实现方法是 }

function GetDataField: string; { 返回数据库字段的名字 }

function GetDataSource: TDataSource; { 返回数据源(Data source)的引用 }

procedure SetDataField(const Value: string); { 给数据库字段名赋值 }

procedure SetDataSource(Value: TDataSource); { 给数据源赋值 }

published { 使属性在设计时可用 }

property DataField: string read GetDataField write SetDataField;

property DataSource: TDataSource read GetDataSource write SetDataSource;

end;

 

……

 

function TDBCalendar.GetDataField: string;

begin

Result := FDataLink.FieldName;

end;

 

function TDBCalendar.GetDataSource: TDataSource;

begin

Result := FDataLink.DataSource;

end;

 

procedure TDBCalendar.SetDataField(const Value: string);

begin

FDataLink.FieldName := Value;

end;

 

procedure TDBCalendar.SetDataSource(Value: TDataSource);

begin

FDataLink.DataSource := Value;

end;

 

  现在,就建立了日历和DataLink的链,此外还有一个更重要的步骤。你必须在日历构建时创建DataLink对象,在日历析构时,撤消DataLink对象。

  ⑶ 初始化DataLink

  在数据相关控制在其存在的期间要不停地访问DataLink对象,因此,必须在其构建函数中创建DataLink创建并且在析构时,撤消DataLink对象,因此要覆盖日历的Create和Destroy方法。

 

type

TDBCalendar=class(TCalendar)

public

constructor Create(Aowna: TComponent); override;

destructor Destroy; override;

end;

 

constructor TDBCalendar Create (Aowner: TComponent);

begin

inherited Create(AOwner);

FReadOnly := True;

FDataLink := TFieldDataLink.Create;

end;

 

destructor TDBCalendar Destroy;

begin

FDataLink.Free;

inherited Destroy;

end;

 

现在,部件已拥有完整的DataLink,但部件还不知从相联的域中读取什么数据。

 

19.3.1.4 响应数据变化

 

  一旦控制拥有了数据联接(DataLink)和描述数据源和数据域的属性。就需在数据记录改变时响应域中数据的变化。

  DataLink对象都有个名为OnDataChange的事件。当数据源指示数据发生变化时,DataLink对象调用任何OnDataChange所联接的事件处理过程。

  要在数据改变时更新数据,就需要给DataLink对象的OnDataChange事件增加事件处理过程。

  下面声明了DataChange方法,并将其赋给DataLink对象的OnDataChange事件:

 

type

TDBCalendar=class(TCalendar)

private

procedure Datachange(Sender: TObject);

end;

 

constructor TDBCalendar Create(AOwner:TComponent);

begin

inherited Create(AOwner);

FReadOnly := True;

FDataLink := TFieldDataLink.Create;

FDataLink.OnDataChange := DataChange;

end;

 

destructor TDBcalendar.Destroy;

begin

FDataLink.OnDataChange := nil;

FDataLink.Free;

inherited Destroy

end;

 

procedure TDBCalendar.DataChange(Sender: TObject);

begin

if FDataLink.Filed=nil then

CalendarDate := 0;

else

CalendarDate := FDataLink.Field.AsDate;

end;

;

-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
最新入库:
 
·实质、过程及意义——阿多尔诺“否定的辩证法”探微
·从Ontology的译名之争看哲学术语的翻译原则
·论马克思主义哲学经典的解释——解释学方法及其在马克
·中国哲学当前的核心与周边问题
·和合学与21世纪文化价值和科技
·中国文化的和合精神与21世纪
·宗教之间理当相互宽容
·上半个世纪的自由主义
·殷周至春秋时期神人关系之演进
·大学之道:构建以“三纲八目”为核心的道德修养体系
相关内容:
 
网友点评:
 
会员名称:
密码:匿名 ·注册·忘记密码?
评论内容:
(最多300个字符)
  查看评论
友情提醒:
 1.库中的资料大都来自互联网、网友上传、各类书籍,在录入的过程中难免会出现错误,恳请网
 友来信指正!
 2.如果网友在本库中未能找到所需要的材料,请登陆到我们的论坛《招考学习网》版块!
 3.考友想加入招考学习网的编辑部,请发信到XueXiWang#Gmail.com(#改为@)附带个人简历
 4.如需转载请注明出处及作者,谢谢合作!
 5.如果您有更好的建议或意见请EMAIL:XueXiWang#Gmail.com (#改为@)
 6.凡标题中有注有“[NO]”字样均不含答案且答案整理中.
 7.如本库中转载文章涉及版权等问题,请相关网站或作者在两周内发邮件通知(EMAIL:  XueXiWang#Gmail.com (#改为@))我们,我们接到通知后立即删除该文章及链接!
你问我答 更多>>