Jump to content


Photo

VirtualColumn Code Posted


  • Please log in to reply
No replies to this topic

#1 wvd_vegt

wvd_vegt

    Master Member

  • Honorable Members
  • PipPipPipPipPip
  • 710 posts
  • Gender:Male
  • Location:the Netherlands

Posted 18 March 2005 - 10:42 PM

Hi all,

Here my latest addition to GridView, a virtual column that asks for data through an Event when it's painted. It also features editing ans calls an event when there is new virtual data.

For this it has to store the Row/Column Index inside each cell as i did not find a 'normal' way to retrieve a cells coordinates (Boki?).

It's not integrated with the columns editor as i could not find documentation on it. So usage is:

CODE
procedure TForm1.DoGetText(Sender: TObject; const ACol, ARow: Integer; var Value: WideString);

begin

 Value := Format('R%dC%d', [ARow, ACol]);

 OutputDebugString(PChar(Format('DoGetText(%d,%d,%s)', [ACol, ARow, Value])));

end;



procedure TForm1.DoSetText(Sender: TObject; const ACol, ARow: Integer;

 const Value: WideString);

begin

 OutputDebugString(PChar(Format('DoSetText(%d,%d,%s)', [ACol, ARow, Value])));

end;



procedure TForm1.Button1Click(Sender: TObject);

var

 vc                : TVirtualColumn;

begin

 vc := GridView1.Columns.Add(TVirtualColumn, 'test') as TVirtualColumn;

 vc.OnGetText := DoGetText;

 vc.OnSetText := DoSetText;

 vc.Options := vc.Options + [coEditing];

 GridView1.AddRow(5);

end;

It adds 5 rows and populates them with row/column numbers.

The first part is the VirtualColumn. It only supports Textual Display because formatting in my opinion is something for the supplier with this kind of virtual data. Save the following as VirtualColumn.pas:

CODE
unit VirtualColumn;



interface



uses

 Classes, CellEditors, Columns, ColumnClasses, Displays, Cells;



type

 TGetTextEvent = procedure(Sender: TObject; const ACol, ARow: Integer; var Value: WideString) of object;

 TSetTextEvent = procedure(Sender: TObject; const ACol, ARow: Integer; const Value: WideString) of object;



 TVirtualCell = class(TCell)

 private

   FCol,

     FRow: Integer;

   FOnGetText: TGetTextEvent;

   FOnSetText: TSetTextEvent;

 protected

   function GetAsBoolean: Boolean; override;

   function GetAsDateTime: TDateTime; override;

   function GetAsFloat: Double; override;

   function GetAsInteger: Integer; override;

   function GetAsString: WideString; override;

   procedure SetAsBoolean(const Value: Boolean); override;

   procedure SetAsDateTime(const Value: TDateTime); override;

   procedure SetAsFloat(const Value: Double); override;

   procedure SetAsInteger(const Value: Integer); override;

   procedure SetAsString(const Value: WideString); override;

 public

   constructor Create(Cells: TCells; Column: TCustomColumn; ACol, ARow: Integer); reintroduce;

 end;



 TVirtualColumn = class(TTextualColumn)

 private

   { Private declarations }

   FTextAfter: WideString;

   FTextBefore: WideString;

   FAutoExecute: Boolean;

   FOnGetText: TGetTextEvent;

   FOnSetText: TSetTextEvent;

   procedure SetAutoExecute(const Value: Boolean);

   procedure SetTextAfter(const Value: WideString);

   procedure SetTextBefore(const Value: WideString);

 protected

   { Protected declarations }

   function GetColumnDisplayClass: TColumnDisplayClass; override;

 public

   { Public declarations }

   procedure Assign(Source: TPersistent); override;

   constructor Create(AOwner: TComponent); override;

   function GetDisplayText(Value: WideString): WideString; override;

   function IsKeyValid(Key: Char): Boolean; override;

   function GetCellEditorClass: TCellEditorClass; override;

   procedure DoGetText(Sender: TObject; const ACol, ARow: Integer; var Value: WideString);

   procedure DoSetText(Sender: TObject; const ACol, ARow: Integer; const Value: WideString);

 published

   { Published declarations }

   property AutoExecute: Boolean read FAutoExecute write SetAutoExecute;

   property OnGetText: TGetTextEvent read FOnGetText write FOnGetText;

   property OnSetText: TSetTextEvent read FOnSetText write FOnSetText;

   property TextAfter: WideString read FTextAfter write SetTextAfter;

   property TextBefore: WideString read FTextBefore write SetTextBefore;

 end;



 TVirtualColumnDisplay = class(TTextualColumnDisplay)

   procedure Paint; override;

 public

   constructor Create(AColumn: TCustomColumn); override;

 end;



implementation



uses

 GridView, SysUtils;



{ TVirtualColumn }



procedure TVirtualColumn.Assign(Source: TPersistent);

begin

 inherited;

 if Source is TVirtualColumn then

   begin

     AutoExecute := TVirtualColumn(Source).AutoExecute;

     TextAfter := TVirtualColumn(Source).TextAfter;

     TextBefore := TVirtualColumn(Source).TextBefore;

   end;

end;



constructor TVirtualColumn.Create(AOwner: TComponent);

begin

 inherited Create(AOwner);

 FAutoExecute := False;

 FTextAfter := '';

 FTextBefore := '';

 DefaultValue := '';

 Options := Options + [coShowTextFitHint];



 SetSortType(stAlphabetic);

 SetColumnType(ctVirtual);

end;



procedure TVirtualColumn.SetAutoExecute(const Value: Boolean);

begin

 FAutoExecute := Value;

end;



procedure TVirtualColumn.SetTextAfter(const Value: WideString);

begin

 FTextAfter := Value;

end;



procedure TVirtualColumn.SetTextBefore(const Value: WideString);

begin

 FTextBefore := Value;

end;



function TVirtualColumn.GetCellEditorClass: TCellEditorClass;

begin

 Result := TTextualEditor;

end;



function TVirtualColumn.GetDisplayText(Value: WideString): WideString;

begin

 Result := FTextAfter + Value + FTextBefore;

end;



function TVirtualColumn.IsKeyValid(Key: Char): Boolean;

begin

 Result := Ord(Key) > 32;

end;



function TVirtualColumn.GetColumnDisplayClass: TColumnDisplayClass;

begin

 Result := TVirtualColumnDisplay;

end;



procedure TVirtualColumn.DoGetText(Sender: TObject; const ACol, ARow: Integer; var Value: WideString);

begin

 if Assigned(FOnGetText) then

   FOnGetText(Sender, ACol, ARow, Value)

 else

   Value := 'n/a';

end;



procedure TVirtualColumn.DoSetText(Sender: TObject; const ACol, ARow: Integer; const Value: WideString);

begin

 if Assigned(FOnSetText) then

   FOnSetText(Sender, ACol, ARow, Value)

//else

//  Value := 'n/a';

end;



{ TVirtualColumnDisplay }



constructor TVirtualColumnDisplay.Create(AColumn: TCustomColumn);

begin

 inherited;

end;



procedure TVirtualColumnDisplay.Paint;

begin

 with Column as TVirtualColumn do

   DrawTextRect(TextBefore + AsString + TextAfter, GetTextRect);

end;



{ TVirtualCell }



constructor TVirtualCell.Create(Cells: TCells; Column: TCustomColumn; ACol, ARow: Integer);

begin

 FCol := ACol;

 FRow := ARow;



 FOnGetText := TVirtualColumn(Column).DoGetText;

 FOnSetText := TVirtualColumn(Column).DoSetText;



 inherited Create(Cells);

end;



function TVirtualCell.GetAsBoolean: Boolean;

begin

 Result := StrToBool(GetAsString);

end;



function TVirtualCell.GetAsDateTime: TDateTime;

begin

 Result := StrToDateTime(GetAsString);

end;



function TVirtualCell.GetAsFloat: Double;

begin

 Result := StrToFloat(GetAsString);

end;



function TVirtualCell.GetAsInteger: Integer;

begin

 Result := StrToInt(GetAsString);

end;



function TVirtualCell.GetAsString: WideString;

begin

 FOnGetText(Self, FCol, FRow, Result)

end;



procedure TVirtualCell.SetAsBoolean(const Value: Boolean);

begin

 SetAsString(BoolToStr(Value, True));

 inherited;

end;



procedure TVirtualCell.SetAsDateTime(const Value: TDateTime);

begin

 SetAsString(DateTimeToStr(Value));

 inherited;

end;



procedure TVirtualCell.SetAsFloat(const Value: Double);

begin

 SetAsString(FloatToStr(Value));

 inherited;

end;



procedure TVirtualCell.SetAsInteger(const Value: Integer);

begin

 SetAsString(IntToStr(Value));

 inherited;

end;



procedure TVirtualCell.SetAsString(const Value: WideString);

begin

 FOnSetText(Self, FCol, FRow, Value);



 inherited;

end;



end.


Then a number of changes the the GridView suite.

1) In columns.pas add ctVirtual to TColumnType

CODE
 TColumnType = (ctAutoInc, ctNone, ctGraphic, ctBoolean, ctDate, ctFloat, ctInteger, ctString, ctLookup, ctVirtual);


and include VirtualColumn to the implementation uses Clause.

2) in Cells.pas add the following to the case statement in TCells.AddRow:

CODE
           ctVirtual: ACell := TVirtualCell.Create(Self, FColumns[i], i, FRowCount);


3) In GridView.pas add to DrawCellData:

CODE
     ctVirtual: Display.AsString := Cell[ACol, ARow].AsString;


and include VirtualColumn to the implementation uses Clause.

and add TVirtualColumn in RegisterColumnsIntoDesigner:

CODE
 RegisterClasses([TGraphicColumn, TCheckBoxColumn, TDateColumn, THtmlColumn,

   TImageColumn, TComboBoxColumn, TNumericColumn, TProgressColumn, TRateColumn,

   TTextualColumn, TVirtualColumn]);


That should be all.

As usual, it's fresh code so there might be a bug. Reports are welcome (and i hope Boki puts in into GridView off-course).
[/code]
G.W. van der Vegt




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users