我在创建查找组件时遇到问题。
我会再试一次......把图像放在一边......
不保存dfm中的属性值...所以为什么,我的属性被分组在一个类中...如果它们是“松散的”将执行setter方法......
我怀疑是......为什么不跑?
我感谢你......
我的属性类
TLookupProperties = class(TPersistent)
private
FDataCharCase: TEditCharCase;
FOnLookupBeforeSearch: TNotifyEvent;
FDataSource: TDataSource;
FOnButtonClick: TNotifyEvent;
FDataTabela: string;
FOnExit: TNotifyEvent;
FDataCondicao: string;
FDataFieldDescricao: string;
FDataFieldCodigo: string;
FOnLookupValidate: TNotifyEvent;
FDataFieldID: String;
published
property OnLookupBeforeSearch: TNotifyEvent read FOnLookupBeforeSearch write FOnLookupBeforeSearch;
property OnLookupExit: TNotifyEvent read FOnExit write FOnExit;
property OnLookupButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
property OnLookupValidate: TNotifyEvent read FOnLookupValidate write FOnLookupValidate;
property DataSource: TDataSource read FDataSource write FDataSource;
property DataFieldID: String read FDataFieldID write FDataFieldID;
property DataFieldCodigo: string read FDataFieldCodigo write FDataFieldCodigo;
property DataFieldDescricao: string read FDataFieldDescricao write FDataFieldDescricao;
property Condicao: string read FDataCondicao write FDataCondicao;
property Tabela: string read FDataTabela write FDataTabela;
property CharCase: TEditCharCase read FDataCharCase write FDataCharCase;
end;
我的组件
TDBLookupFrame = class(TFrame)
PnlTotal: TPanel;
btnButton: TSpeedButton;
edtCodigo: TDBEdit;
lblDescricao: TDBText;
procedure edtCodigoExit(Sender: TObject);
procedure btnButtonClick(Sender: TObject);
procedure edtCodigoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure edtCodigoKeyPress(Sender: TObject; var Key: Char);
strict private
procedure SetarResult(AZerar: Boolean = False);
procedure Validar(Sender: TObject);
private
FLookupView: TLookupView;
FLookupProperties: TLookupProperties;
procedure SetLookupProperties(const Value: TLookupProperties);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property LookupProperties: TLookupProperties read FLookupProperties write SetLookupProperties;
end;
procedure register;
implementation
uses System.SysUtils;
{$R *.dfm}
procedure register;
begin
RegisterComponents('Hebran',[TDBLookupFrame]);
end;
procedure TDBLookupFrame.SetLookupProperties(const Value: TLookupProperties);
begin
FLookupProperties := Value;
edtCodigo.CharCase := FLookupProperties.CharCase;
FLookupView.Tabela := FLookupProperties.Tabela;
FLookupView.CondicaoAdicional := FLookupProperties.Condicao;
if Assigned(FLookupProperties.DataSource) then
begin
edtCodigo.DataSource := FLookupProperties.DataSource;
lblDescricao.DataSource := FLookupProperties.DataSource;
FLookupProperties.DataFieldDescricao := FLookupProperties.DataFieldCodigo;
lblDescricao.DataField := FLookupProperties.DataFieldDescricao;
end;
end;
constructor TDBLookupFrame.Create(AOwner: TComponent);
begin
inherited;
FLookupView := TLookupView.Create(Nil);
FLookupProperties := TLookupProperties.Create;
LookupProperties.Condicao := '';
LookupProperties.CharCase := ecNormal;
end;
答案 0 :(得分:2)
查看此处(将DFM流式传输到组件时调用):
procedure TDBLookupFrame.SetLookupProperties(const Value: TLookupProperties);
begin
FLookupProperties := Value;
edtCodigo.CharCase := FLookupProperties.CharCase;
FLookupView.Tabela := FLookupProperties.Tabela;
FLookupView.CondicaoAdicional := FLookupProperties.Condicao;
if Assigned(FLookupProperties.DataSource) then
begin
edtCodigo.DataSource := FLookupProperties.DataSource;
lblDescricao.DataSource := FLookupProperties.DataSource;
FLookupProperties.DataFieldDescricao := FLookupProperties.DataFieldCodigo;
lblDescricao.DataField := FLookupProperties.DataFieldDescricao;
end;
end;
您正在致电
FLookupProperties := Value;
的确,当依靠IDE为您自动完成此操作时,它也会添加此功能。但是,根据您的情况,您不应该指定指针 - 因为您现在正在引用TLookupProperties
的原始实例并将指针替换为您的副本。这也会泄漏内存,您已经在构造函数中创建了FLookupProperties
,但由于您已经替换了指针,因此无法再引用该实例。
你应该改为呼叫
FLookupProperties.Assign(Value);
这将确保您创建原始值的完整副本,而不是仅仅引用实例(在该点之后可能会或可能不会自由)。
您的TLookupProperties
也应该覆盖TPersistent.Assign
,以便您可以将数据从一个实例复制到另一个实例。同样,对于任何类型的其他TPersistent
属性,请勿使用:=
因为它只是复制指针。相反,也可以在它们上使用.Assign
。
答案 1 :(得分:2)
尝试更像这样的东西:
interface
uses
Classes, Forms, ...;
type
TDBLookupFrame = class;
TLookupProperties = class(TPersistent)
private
FOwner: TDBLookupFrame;
FDataCharCase: TEditCharCase;
FDataSource: TDataSource;
FDataTabela: string;
FDataCondicao: string;
FDataFieldDescricao: string;
FDataFieldCodigo: string;
FDataFieldID: String;
FOnChange: TNotifyEvent;
FOnButtonClick: TNotifyEvent;
FOnExit: TNotifyEvent;
FOnLookupBeforeSearch: TNotifyEvent;
FOnLookupValidate: TNotifyEvent;
procedure Changed;
procedure SetDataSource(const: Value: TDataSource);
procedure SetDataFieldID(const Value: String);
procedure SetDataFieldCodigo(const Value: string);
procedure SetDataFieldDescricao(const Valu: string);
procedure SetCondicao(const Value: string);
procedure SetTabela(const Value: string);
procedure SetCharCase(const Value: TEditCharCase);
public
constructor Create(AOwner: TDBLookupFrame);
procedure Assign(Source: TPeristent); override;
published
property DataSource: TDataSource read FDataSource write SetDataSource;
property DataFieldID: String read FDataFieldID write SetDataFieldID;
property DataFieldCodigo: string read FDataFieldCodigo write SetDataFieldCodigo;
property DataFieldDescricao: string read FDataFieldDescricao write SetDataFieldDescricao;
property Condicao: string read FDataCondicao write SetDataCondicao;
property Tabela: string read FDataTabela write SetDataTabela;
property CharCase: TEditCharCase read FDataCharCase write SetDataCharCase;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnLookupBeforeSearch: TNotifyEvent read FOnLookupBeforeSearch write FOnLookupBeforeSearch;
property OnLookupExit: TNotifyEvent read FOnExit write FOnExit;
property OnLookupButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
property OnLookupValidate: TNotifyEvent read FOnLookupValidate write FOnLookupValidate;
end;
TDBLookupFrame = class(TFrame)
PnlTotal: TPanel;
btnButton: TSpeedButton;
edtCodigo: TDBEdit;
lblDescricao: TDBText;
procedure edtCodigoExit(Sender: TObject);
procedure btnButtonClick(Sender: TObject);
procedure edtCodigoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure edtCodigoKeyPress(Sender: TObject; var Key: Char);
strict private
procedure SetarResult(AZerar: Boolean = False);
procedure Validar(Sender: TObject);
private
FLookupView: TLookupView;
FLookupProperties: TLookupProperties;
procedure LookupPropertiesChanged(Sender: TObject);
procedure SetLookupProperties(const Value: TLookupProperties);
protected
procedure Loaded; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property LookupProperties: TLookupProperties read FLookupProperties write SetLookupProperties;
end;
procedure Register;
implementation
uses
System.SysUtils;
{$R *.dfm}
constructor TLookupProperties.Create(AOwner: TDBLookupFrame);
begin
inherited Create;
FOwner := AOwner;
FDataCondicao := '';
FDataCharCase := ecNormal;
end;
procedure TLookupProperties.Changed;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TLookupProperties.SetDataSource(const: Value: TDataSource);
begin
if FDataSource <> Value then
begin
if FDataSource <> nil then
FDataSource.RemoveFreeNotification(FOwner);
FDataSource := Value;
if FDataSource <> nil then
FDataSource.FreeNotification(FOwner);
Changed;
end;
end;
procedure TLookupProperties.SetDataFieldID(const Value: String);
begin
if FDataFieldID <> Value then
begin
FDataFieldID := Value;
Changed;
end;
end;
procedure TLookupProperties.SetDataFieldCodigo(const Value: string);
begin
if FDataFieldCodigo <> Value then
begin
FDataFieldCodigo := Value;
Changed;
end;
end;
procedure TLookupProperties.SetDataFieldDescricao(const Valu: string);
begin
if FDataFieldDescricao <> Value then
begin
FDataFieldDescricao := Value;
Changed;
end;
end;
procedure TLookupProperties.SetCondicao(const Value: string);
begin
if FDataCondicao <> Value then
begin
FDataCondicao := Value;
Changed;
end;
end;
procedure TLookupProperties.SetTabela(const Value: string);
begin
if FDataTabela <> Value then
begin
FDataTabela := Value;
Changed;
end;
end;
procedure TLookupProperties.SetCharCase(const Value: TEditCharCase);
begin
if FDataCharCase <> Value then
begin
FDataCharCase := Value;
Changed;
end;
end;
procedure TLookupProperties.Assign(Source: TPeristent);
var
Src: TLookupProperties;
begin
if Source is TLookupProperties then
begin
Src := TLookupProperties(Source);
FDataCharCase := Src.FDataCharCase;
SetDataSource(Src.FDataSource);
FDataTabela := Src.FDataTabela;
FDataCondicao := Src.FDataCondicao;
FDataFieldDescricao := Src.FDataFieldDescricao;
FDataFieldCodigo := Src.FDataFieldCodigo;
FDataFieldID := Src.FDataFieldID;
Changed;
end else
inherited;
end;
constructor TDBLookupFrame.Create(AOwner: TComponent);
begin
inherited;
FLookupView := TLookupView.Create(nil);
FLookupProperties := TLookupProperties.Create(Self);
end;
destructor TDBLookupFrame.Destroy;
begin
FLookupView.Free;
FLookupProperties.Free;
inherited;
end;
procedure TDBLookupFrame.Loaded;
begin
inherited;
LookupPropertiesChanged(nil);
end;
procedure TDBLookupFrame.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (AComponent = FLookupProperties.FDataSource) and (Operation = opRemove) then
FLookupProperties.FDataSource := nil;
end;
procedure TDBLookupFrame.LookupPropertiesChanged(Sender: TObject);
begin
if (ComponentState * [csLoading, csReading]) <> [] then
Exit;
edtCodigo.CharCase := FLookupProperties.CharCase;
FLookupView.Tabela := FLookupProperties.Tabela;
FLookupView.CondicaoAdicional := FLookupProperties.Condicao;
edtCodigo.DataSource := FLookupProperties.DataSource;
lblDescricao.DataSource := FLookupProperties.DataSource;
FLookupProperties.DataFieldDescricao := FLookupProperties.DataFieldCodigo;
lblDescricao.DataField := FLookupProperties.DataFieldDescricao;
end;
procedure TDBLookupFrame.SetLookupProperties(const Value: TLookupProperties);
begin
if FLookupProperties <> Value then
FLookupProperties.Assign(Value);
end;
procedure Register;
begin
RegisterComponents('Hebran', [TDBLookupFrame]);
end;
答案 2 :(得分:0)