1

日付プロパティを持つウィンドウ化されていないコンポーネントがあります。日付フィールドへの読み取りおよび書き込み機能を使用して、このコンポーネント データを認識させたいと考えています。(つまり、実行時に日付を変更した場合、新しい日付プロパティ値をデータセットに書き込みたいと思います。)例をグーグルで検索しましたが、何も見つかりませんでした。TDbLabel などの読み取り専用の例がいくつか見つかりましたが、データセットへの変更の書き込みを許可する例はありません。誰かが私に例を挙げてくれれば、私は感謝します。

4

2 に答える 2

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.
于 2012-06-05T08:12:48.773 に答える
0

ちょっとしたコードになりますが、値が変更されたときにトリガーされるイベントがコンポーネントにある場合、それを使用して更新された値をデータセットに送信できます (dsEdit状態にある場合)。また、データセットがいつ変更されるかを知るために、さまざまなTDataSource イベントを処理する必要があります。

于 2012-06-05T02:45:05.653 に答える