控制Delphi是否存储属性的方法是在属性声明后面加stored指令后跟True或False或者是布尔方法名你可以给任何属性的声明或重声明加stored表达式下面的代码显示了部件声明三种新属性一个属性是总是要存储一个是不存第三个则决定于布尔方法的值
type
TSampleCompiment = class(TComponent)
protected
function storeIt: Boolean;
public { 正常情况下在不存 }
property Important: Integer stored True; { 总是存储 }
published { 正常情况下保存 }
property UnImportant: Integer stored False; { 不存 }
property Sometimes: Integer stored StoreIt; { 存储依赖于函数值 }
end;
④ 载入后的初始化
在部件从存储的描述中读取所有的属性后它调用名为Loaded的虚方法这提供了按需要执行任何初始化的机会调用Loaded是在窗体和它的控制显示之前因此不需要担心初始化会带来屏幕闪烁
在部件载入属性时初始化它要覆盖Loaded方法
在Loaded方法中要做的第一件事是调用继承的Loaded方法这使得在你的部件执行初始化之前任何继承的属性都已初始化
下面的代码来自于TDatabase部件在装入后TDatabase试图重建在它存储时已打开的连接并描述在连接发生异常时如何处理
procedure TDatabaseLoaded
begin
inherited Loaded; { 总是先调用继承的方法 }
Modified; { 设置内部标志 }
try
if FStreamedConnected then Open; { 重建联接 }
except
if csDesigning in ComponentState then { 在设计时 }
ApplicationHandleException(self) { 让Delphi处理异常 }
else raise; { 否 则 }
end;
end;
Delphi部件编程实例
创建数据库相关的日历控制TDBCalendar
当处理数据库联接时将控制和数据直接相联是很重要的就是说应用程序可以建立控制与数据库之间的链Delphi包括了数据相关的标签编辑框列表框和栅格用户可以使自己的控制与数据相关
数据相关有若干等级最简单的是只读数据相关或数据浏览以及反映数据库当前状态的能力比较复杂的是数据相关的编辑也即用户可以在控制上操作数据库中的数据
在本部分中将示例最简单的情况即创建联接数据库的单个字段的只读控制本例中将使用Component Palette的Samples页中的TCalendar部件
创建数据相关的日历控制包括下列几步
● 创建和注册部件
● 使控制只读
● 增加数据联接(Data Link)
● 响应数据改变
创建和注册部件
每个部件的创建都从相同的方式开始在本例中将遵循下列过程
● 将部件库单元命名为DBCal
● 从TCalendar继承一个新部件名为TDBCalendar
● 在Component Palette的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
使控制只读
因为这个数据日历以只读方式响应数据所以用户不能在控制中改变数据并指望它们反映到数据库中
使日历只读包含下列两步
● 增加只读属性
● 允许所需的更新
增加只读属性
给日历控制增加只读选项是直接过程通过增加属性可以提供在设计时使控制只读的方法当属性值被设为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 TDBCalendarCreate(Aowner: TComponent)
begin
inherited Create(AOwner)
FReadOnly := True;
end;
⑵ 覆盖SelectCell方法使得当控制是只读时不允许选择
function TDBCalendarSelectCell(ACol Arow: Longint) Boolean;
begin
if FReadOnly then
Result := False
else
Result := inherited SelectCell(AcolARow)
end;
还要在TDBcalendar的声明中声明SelectCell
如果现在将Calendar加入窗体会发现部件完全忽略鼠标和击键事件而且当改变日期时也不能改变选择的位置下面将使控制响应更新
允许所需的更新
只读日历使用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 TDBCalendarSelectCell(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;
现在日历仍旧不允许用户修改但当改变日期属性时能正确反映改变目前已有了一个真正只读控制下一步是增加数据浏览能力
增加数据联接
控制和数据库的联接是由一个名为DataLink的对象处理Delphi提供了几种类型的Datalink将控制与数据库单个域相联的DataLink对象是TFieldDatalinkDelphi也提供了与整个表相联的DataLink
一个数据相关控制拥有DataLink对象就是说控制负责创建和析构DataLink
要建立作为拥有对象的Datalink要执行下列三步
● 声明对象域
● 声明访问属性
● 初始化DataLink
⑴ 声明对象域
每个部件要为其拥有对象声明一个对象域因此日历对象DataLink 声明TFieldDataLink类型的域
日历部件中DataLink的声明如下
type
TDBCalendar = class(TSampleCalendar)
private
FDataLink: TFieldDataLink;
…
end;
⑵ 声明访问属性
每一个数据相关控制有一个DataSource属性该属性描述应用程序给控制提供数据的数据源而且访问单个域的数据库还需要一个DataField 属性描述数据源中的域
[] [] [] []