为何字段没有下拉框(50分)

  • 主题发起人 主题发起人 TIMDONG
  • 开始时间 开始时间
T

TIMDONG

Unregistered / Unconfirmed
GUEST, unregistred user!
在控件开发时,声明一个字段属性(property FieldX:string read GetFieldX write SetFieldX)
,为什么安装后没有下拉列表,请教各位高手如何解决?
 
field属性只能有一个的。多的请用Index标记,在声明属性时用Index
 
楼上的人兄可以说得详细一点吗
最好有示范代码
 
声明枚举类型
TEnuValue = (a, b, c, d)
声明变量
FValue: TEnuValue;
公开属性
property Value: TEnuValue read FValue write FValue;
 
To djdsz:
尝试你的方法好像不行。
To LanFairy:
我指的是数据库字段,象DBEdit的DataField属性,我查看VCL源码字段属性声明为String
可是我也声明为字符型却没有下拉框。请教高手详细告知。
 
你放在哪儿的?published下吗?
 
To zhangkan:
当然放在了Published部分,在属性编辑器中有显示但没有下拉框。
 
在数据感知的构件中,你如果要使得tfielddatalink具有下拉样式,要把tfielddatalink的
datasource指向tdatasource,也就是要把field和datasource关联起来
 
你需要注册该属性的属性编辑器才行。如 TDBEdit 是这样注册它的 DataField 属性的
见 dbreg.pas 的 Register 过程中:
RegisterPropertyEditor(TypeInfo(string), TDBEdit, 'DataField', TDataFieldAggProperty);
如果你的控件中也有名为 DataSource 属性,你可以模仿着注册你的 Fieldx 属性的属性
编辑器,假设你的控件类别是 TYourControl:
RegisterPropertyEditor(TypeInfo(string), TYourControl, 'FieldX', TDataFieldAggProperty);
第一个参数一般是 TypeInfo(你的属性的类型) 的格式,这里也是 string;
第二个参数是你的控件的类,这里是 TYourControl;
第三个参数是你要编辑的属性的名字,是 string 类型,按你的声明是 'FieldX';
第四个参数是你为该属性定义的属性编辑器的类,都是由 TPropertyEditor 继承而来的。
你应该在单元的 Register 过程中调用该注册过程。
至于如何定义自己的属性编辑器,最好看看 dsgnIntf.pas 和 /Source/Property editors
目录下的源程序,一下子说不清的。
 
TO gutian:
不太明白你的意思,现贴上代码(从TDateTimePicker继承,可以与DataSet中的日期字段
连接),有空指点一二.

TO bbkxjy:
我只是要显示连接的DataSource中的下拉字段好像不用那么麻烦吧!

代码如下:

unit DateTimePickerTim;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, db, dbCtrls;

type
TDateTimePickerTim = class(TDateTimePicker)
private
FTimDataLink:TFieldDataLink;
function GetTimDataField: string;
function GetTimDataSource: TDataSource;
procedure SetTimDataField(const Value: string);
procedure SetTimDataSource(const Value: TDataSource);
procedure TimDataChange(Sender:TObject);
procedure TimUpdateData(Sender:TObject);
procedure CMExit(var msg:TWMNoParams);message CM_EXIT;

protected
procedure Change;override;

public
constructor Create(aOwner:TComponent);override;
destructor Destroy;override;

published
property TimDataField:string read GetTimDataField write SetTimDataField;
property TimDataSource:TDataSource read GetTimDataSource write SetTimDataSource;

end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('TimDatabase', [TDateTimePickerTim]);
end;

{ TDateTimePickerTim }

constructor TDateTimePickerTim.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FTimDataLink:=TFieldDataLink.Create;
FTimDataLink.OnDataChange:=TimDataChange;
FTimDataLink.OnUpdateData:=TimUpdateData;

end;

procedure TDateTimePickerTim.TimDataChange(Sender: TObject);
begin
if FTimDataLink.Field=nil then
Date:=0
else
Date:=FTimDataLink.Field.AsDateTime;
end;

destructor TDateTimePickerTim.Destroy;
begin
FTimDataLink.OnDataChange:=nil;
FTimDataLink.OnUpdateData:=nil;
FTimDataLink.Free;
inherited Destroy;
end;

function TDateTimePickerTim.GetTimDataField: string;
begin
result:=FTimDataLink.FieldName;
end;

function TDateTimePickerTim.GetTimDataSource: TDataSource;
begin
result:=FTimDataLink.DataSource;
end;

procedure TDateTimePickerTim.SetTimDataField(const Value: string);
begin
FTimDataLink.FieldName:=value;
end;

procedure TDateTimePickerTim.SetTimDataSource(const Value: TDataSource);
begin
FTimDataLink.DataSource:=value;
end;

procedure TDateTimePickerTim.TimUpdateData(Sender: TObject);
var
MyDate:TDate;
begin
MyDate:=StrToDate(FormatDateTime('yyyy-m-d', DateTime));
FTimDataLink.Edit;
FTimDataLink.Field.AsDateTime:=MyDate;
end;

procedure TDateTimePickerTim.Change;
begin
FTimDataLink.Modified;
inherited Change;
end;

procedure TDateTimePickerTim.CMExit(var msg: TWMNoParams);
begin
try
FTimDataLink.UpdateRecord;
except
on Exception do SetFocus;
end;//try
inherited;
end;

end.
 
其实对于你这个控件也不是很复杂,你可以照着下面修改一下你的单元:
unit DateTimePickerTim;

interface

uses
...,DBReg, DsgnIntf; //加上 DBReg,DsgnIntf;
type
//你原来的声明
TDateTimePickerTim = class(TDateTimePicker)
...
end;
//声明属性编辑器
TTimFieldProperty = Class(TDBStringProperty)
public
procedure GetValueList(List: TStrings); override;
end;
...

implementation
uses TypInfo; //加上 TypInfo,GetPropertyValue 中用到
...
//以上是你原来的实现
{ utility function}
function GetPropertyValue(Instance: TPersistent; const PropName: string): TPersistent;
var
PropInfo: PPropInfo;
begin
Result := nil;
PropInfo := TypInfo.GetPropInfo(Instance.ClassInfo, PropName);
if (PropInfo <> nil) and (PropInfo^.PropType^.Kind = tkClass) then
Result := TObject(GetOrdProp(Instance, PropInfo)) as TPersistent;
end;

procedure TTimFieldProperty.GetValueList(List: TStrings);
var
DataSource: TDataSource;
begin
DataSource := GetPropertyValue(GetComponent(0), 'TimDataSource') as TDataSource;
if (DataSource <> nil) and (DataSource.DataSet <> nil) then
DataSource.DataSet.GetFieldNames(List);
end;
...
//Register 过程中改一下
procedure Register;
begin
RegisterComponents('TimDatabase', [TDateTimePickerTim]);
RegisterPropertyEditor(TypeInfo(string), TDateTimePickerTim, 'TimDataField', TTimFieldProperty);
end;
end.

上面我已安装试过了,需要的话我可以把改过的单元发给你。
 
TO bbkxjy:
Please send to me: iAddress@china.com. Thanks a lot.
 
TIMDONG:
已发过去了,请查收。
 
TO bbkxjy:
可以也发给我一份吗,谢谢!
xie_p_f@21cn.com
 
xie_p_f:
你好,发过去了,请查收。
 
谢谢各位!
 
如果在BCB 5中又如何呢?
 
后退
顶部