2012-06-05 38 views
1

我有一個非窗口組件具有日期屬性。我想通過對日期字段的讀寫功能來識別組件數據。 (換句話說,如果我在運行時更改了日期,我想將新的日期屬性值寫入數據集。)我已經搜索了一些示例,但是我一直未找到任何示例。發現了幾個只讀的例子,例如TDbLabel,但沒有一個允許將更改寫入數據集。如果有人能指點我一個例子,我將不勝感激。使非窗口組件數據意識

+1

你怎麼指望能夠允許用戶在運行時更改日期控件的值,如果它不是一個窗口控制? –

+0

@Rob McDonell如果用戶是程序員(我,但不一定是熟練的程序員),則該屬性已發佈。所以,我可以將其設置在我的程序中的任何位置,就像其他已發佈(或公開)的屬性一樣。 –

+0

是的,但是如果它是程序員在控件上設置已發佈的屬性,程序員也可以直接更新數據集,因此不需要數據感知控件。 –

回答

0

它只是一些代碼,但如果您的組件在其值發生更改時觸發了事件,則可以使用該組件將更新的值發送到數據集(如果它處於dsEdit狀態)。您還需要處理各種TDataSource Events以瞭解數據集何時更改。

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. 
+0

非常感謝。不知道爲什麼,但我有一個真正的心理障礙。此外,謝謝你回答這個問題,而不是問我爲什麼會這麼笨,以至於問這個問題。 –