TcxCustomDataSource
DevExpressのTcxGridてグリッドコントロール、データベースのデータ一覧とかで良く使ってます。
今回は、データベースじゃなく自分で定義したデータとTcxGridを連携する時に使うTcxCustomDataSourceの使い方をメモ。
とりあえずデータクラスを定義
TUserData = class private FId: Integer; FName: String; public property Id: Integer read FId write FId; property Name: String read FName write FName; end;
Gridと連携する上で、実装しないといけないメソッドは GetRecordCount、GetValue、SetValue、InsertRecord、AppendRecord、DeleteRecordの6つ。
まあ、グリッド上ではデータ表示するだけで編集とか一切無しって場合はGetRecordCount、GetValueの二つで良いかと。編集する場合は、SetValueが必要ですね。
後のメソッド、InsertRecord、AppendRecord、DeleteRecordの3つはViewのOptionsDataのInserting、Appending、DeletingをTrueに設定した時に実装する必要有り。
実装すると以下のような感じに
TUserDataSource = class(TcxCustomDataSource) private FItems: TObjectList<TUserData>; protected function AppendRecord: TcxDataRecordHandle; override; function InsertRecord(ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle; override; procedure DeleteRecord(ARecordHandle: TcxDataRecordHandle); override; function GetRecordCount: Integer; override; function GetRecordHandle(ARecordIndex: Integer): TcxDataRecordHandle; override; function GetValue(ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle): Variant; override; procedure SetValue(ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle; const AValue: Variant); override; public constructor Create; destructor Destroy; override; end; function TUserDataSource.AppendRecord: TcxDataRecordHandle; var Im: TUserData; begin Im := TUserData.Create; FItems.Add(Im); Result := TcxDataRecordHandle(Im); DataChanged; end; constructor TUserDataSource.Create; begin FItems := TObjectList<TUserData>.Create; end; procedure TUserDataSource.DeleteRecord(ARecordHandle: TcxDataRecordHandle); var Idx: Integer; begin Idx := FItems.IndexOf(ARecordHandle); if Idx <> -1 then FItems.Delete(Idx); DataChanged; end; destructor TUserDataSource.Destroy; begin FreeAndNil(FItems); inherited; end; function TUserDataSource.GetRecordCount: Integer; begin Result := FItems.Count; end; function TUserDataSource.GetRecordHandle( ARecordIndex: Integer): TcxDataRecordHandle; begin Result := TcxDataRecordHandle(FItems.Items[ARecordIndex]); end; function TUserDataSource.GetValue(ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle): Variant; var ColumnId: Integer; Im: TUserData; begin ColumnId := GetDefaultItemID(Integer(AItemHandle)); Im := TUserData(ARecordHandle); case ColumnId of 0: Result := Im.Id; 1: Result := Im.Name; end; end; function TUserDataSource.InsertRecord(ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle; var Idx: Integer; Im: TUserData; begin Idx := FItems.IndexOf(ARecordHandle); Im := Nil; if Idx <> -1 then begin Im := TUserData.Create; FItems.Insert(Idx, Im); end; Result := Im; DataChanged; end; procedure TUserDataSource.SetValue(ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle; const AValue: Variant); var ColumnId: Integer; Im: TUserData; begin ColumnId := GetDefaultItemID(Integer(AItemHandle)); Im := TUserData(ARecordHandle); case ColumnId of 0: Im.Id := AValue; 1: Im.Name := AValue; end; end;
InsertRecord、AppendRecord、DeleteRecordの3つを実装した時は、リストのデータを更新した後、DataChangedを実行しないとデータの更新が反映されないので忘れないように注意かなぁ。