我有一个带有日期属性的非窗口组件。我希望通过对日期字段的读写功能来识别此组件数据。 (换句话说,如果我在运行时更改日期,我想将新的日期属性值写入数据集。)我已经搜索了示例,但我找不到任何。找到了几个只读示例,例如TDbLabel,但没有一个允许将更改写入数据集。如果有人能指出我的例子,我将不胜感激。
答案 0 :(得分:1)
以下是您的问题的通用代码方法
unit Unit1;
interface
uses
Classes
,DB
,DBCtrls
;
type
TDataAwareComponent = class(TComponent)
private
{ private declarations }
FDataLink : TFieldDataLink;
FFromDateChange : Boolean;
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetReadOnly: Boolean;
procedure SetDataField(const Value: string);
procedure SetDataSource(const Value: TDataSource);
procedure SetReadOnly(const Value: Boolean);
function GetDateProperty: TDateTime;
procedure SetDateProperty(const Value: TDateTime);
protected
{ protected declarations }
procedure DataChange(Sender : TObject);
public
{ public declarations }
constructor Create(AOwner : TComponent);override;
destructor Destroy;override;
public
property Field : TField read GetField;
property DateProperty : TDateTime read GetDateProperty write SetDateProperty;
published
{ published declarations }
property DataSource : TDataSource read GetDataSource write SetDataSource;
property DataField : string read GetDataField write SetDataField;
property ReadOnly : Boolean read GetReadOnly write SetReadOnly;
end;
implementation
{ TDataAwareComponent }
{------------------------------------------------------------------------------}
constructor TDataAwareComponent.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
end;
{------------------------------------------------------------------------------}
destructor TDataAwareComponent.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
inherited;
end;
{------------------------------------------------------------------------------}
procedure TDataAwareComponent.DataChange(Sender: TObject);
begin
// Here a visual object would display the underlying field value.
// For example if this component was a TEdit
// the code would be something like
{ if FDataLink.Active then
Self.Text := Field.AsString;
And on the exit event of the TEdit the code would be reversed
so the field can take the value the user entered.
Since you do not need any UI interaction propably this event
is useless to you.
}
// Of course there are more issues you should cover to
// have a complete working solution.
// This is only demostration code.
end;
{------------------------------------------------------------------------------}
function TDataAwareComponent.GetDataField: string;
begin
Result := FDataLink.FieldName
end;
{------------------------------------------------------------------------------}
function TDataAwareComponent.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
{------------------------------------------------------------------------------}
function TDataAwareComponent.GetDateProperty: TDateTime;
begin
//You do not need a separate property since you can access directly the field value.
Result := 0;
if Assigned(Field) and (Field.DataType in [ftTime,ftDate,ftDateTime] then
Result := Field.AsDateTime;
end;
{------------------------------------------------------------------------------}
function TDataAwareComponent.GetField: TField;
begin
Result : FDataLink.Field;
end;
{------------------------------------------------------------------------------}
function TDataAwareComponent.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
{------------------------------------------------------------------------------}
procedure TDataAwareComponent.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
{------------------------------------------------------------------------------}
procedure TDataAwareComponent.SetDataSource(const Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
{------------------------------------------------------------------------------}
procedure TDataAwareComponent.SetDateProperty(const Value: TDateTime);
begin
if Assigned(Field) then
begin
FFromDateChange := True;
try
Field.DataSet.Edit;
Field.Value := Value;
finally
FFromDateChange := False;
end;
end;
end;
{------------------------------------------------------------------------------}
procedure TDataAwareComponent.SetReadOnly(const Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
{------------------------------------------------------------------------------}
end.
答案 1 :(得分:0)
这是一些代码,但如果您的组件在其值发生变化时触发了事件,则可以使用该值将更新值发送到数据集(如果它处于dsEdit
状态。您还需要处理各种TDataSource Events以了解数据集何时发生变化。