I would like to know if is it possible to insert a custom component in a cell of the TMSFNCgrid.
I have a component descenting from tcustomcomponent, is ti possible, and how to, display my own component in a cell?
Thank you,
Andrea
I forgot ot mention:
Lazarus 1.6.2 FPC 3.0.0
Hi,
Sorry this is not possible, the grid only allows painting. There is currently no way to add interactive controls.
Ok thanks.
So is it possible to overload the painting method?
My own control should paint the cell taking into account the cell text.
How can I use my TOwnControl.Canvas and TMyOwnControl.Paint method inside tmsfncgrid?
Hi,
Yes, you can return a custom cell class by overriding from TTMSFMXGridCell. then you can override the Draw method and use the AGraphics parameter to paint anything you like.
type
TMyGridCell = class(TTMSFNCGridCell)
procedure Draw(AGraphics: TTMSFNCGraphics; ADrawText: Boolean; ADrawBackGround: Boolean; ADrawBorder: Boolean); override;
end;
procedure TForm2.TMSFNCGrid1GetCellClass(Sender: TObject; ACol, ARow: Integer;
var CellClassType: TTMSFNCGridCellClass);
begin
CellClassType := TMyGridCell;
end;
I tried but accessing AGraphics all the grid is painted out, not the single cell.
Below a small code sample.
procedure TMyGridCell.Draw(AGraphics: TTMSFNCGraphics; ADrawText: Boolean;
ADrawBackGround: Boolean; ADrawBorder: Boolean);
var
myDrawer: TMSDrawer;
begin
myDrawer := TMSDrawer.Create();
myDrawer.Width := AGraphics.Canvas.Width;
myDrawer.Height := AGraphics.Canvas.Height;
myDrawer.Draw(AGraphics.Canvas); // it draws on canvas
inherited Draw(AGraphics, False, False, False);
end;
all the grid (except fixed rows and columns) is painted out. I would like to paint a single cell separately.
What I am doing wrong?
You only need to return TMyGridCell for the cell you wish to custom paint.
the above code is returning a TMyGridCell for all cells.
procedure TForm1.TMSFNCGrid1GetCellClass(Sender: TObject; ACol, ARow: Integer;
var CellClassType: TTMSFNCGridCellClass);
begin
if (ACol = 3) and (ARow = 4) then
CellClassType := TMyGridCell;
end;
Sorry, I forgot to mention but I did it
procedure TForm1.TMSFNCGrid1GetCellClass(Sender: TObject; ACol, ARow: Integer;
var CellClassType: TTMSFNCGridCellClass);
begin
if ACol = 1 then
CellClassType := TMyGridCell;
end;
Can you post the full sample code you have meanwhile setup so we can investigate here what exactly is going wrong?
I cannot upload the full source, but here a sample that behave the same.
In this demo I am simply drwaing on AGraphics.Canvas
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
LCLTMSFNCGrid, LCLTMSFNCGridCell, LCLTMSFNCGraphics, LCLTMSFNCCustomGrid;
type
{ TForm1 }
TForm1 = class(TForm)
TMSFNCGrid1: TTMSFNCGrid;
procedure TMSFNCGrid1GetCellClass(Sender: TObject; ACol, ARow: Integer;
var CellClassType: TTMSFNCGridCellClass);
private
{ private declarations }
public
{ public declarations }
end;
{ TMyGridCell }
TMyGridCell = class(TTMSFNCGridCell)
procedure Draw(AGraphics: TTMSFNCGraphics; ADrawText: Boolean; ADrawBackGround: Boolean; ADrawBorder: Boolean); override;
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.TMSFNCGrid1GetCellClass(Sender: TObject; ACol, ARow: Integer;
var CellClassType: TTMSFNCGridCellClass);
begin
if ACol = 1 then
CellClassType:= TMyGridCell;
end;
{ TMyGridCell }
procedure TMyGridCell.Draw(AGraphics: TTMSFNCGraphics; ADrawText: Boolean;
ADrawBackGround: Boolean; ADrawBorder: Boolean);
begin
with AGraphics do
begin
Canvas.Line(0,0, Canvas.Width,Canvas.Height);
Canvas.Line(0,Canvas.height,Canvas.width,0);
end;
inherited Draw(AGraphics, ADrawText, ADrawBackGround, ADrawBorder);
end;
end.
Hi,
The coordinates for drawing are relative to the top, left coordinates of the grid. Also, you should use the AGraphics drawing functionality instead of using the canvas.
procedure TMyGridCell.Draw(AGraphics: TTMSFNCGraphics; ADrawText,
ADrawBackGround, ADrawBorder: Boolean);
begin
inherited;
AGraphics.Stroke.Color := gcRed;
AGraphics.Stroke.Kind := gskSolid;
AGraphics.DrawLine(PointF(Left, Top), PointF(Left + Width, Top + Height));
end;
I already have a n object that draws what I need.
It can draw a canvas or eventually give a bitmap as result of a function.
I don't want to use AGraphics drawing functionalities but I woul like to use my custom drawer.
Any suggestion?
If you first call inherited Draw... and then call your drawing functionality using the Canvas, does it then work?
Like below? (Anyway same behaviour, a cross all over the grid)
procedure TMyGridCell.Draw(AGraphics: TTMSFNCGraphics; ADrawText: Boolean;
ADrawBackGround: Boolean; ADrawBorder: Boolean);
begin
inherited Draw(AGraphics, ADrawText, ADrawBackGround, ADrawBorder);
with AGraphics do
begin
Canvas.Line(0,0, Canvas.Width,Canvas.Height);
Canvas.Line(0,Canvas.height,Canvas.width,0);
end;
end;
As already explained, the coordinates (0, 0) are based on the grid and not on the grid cell. You can use the following code that should paint a line inside the grid cell:
procedure TMyGridCell.Draw(AGraphics: TTMSFNCGraphics; ADrawText: Boolean;
ADrawBackGround: Boolean; ADrawBorder: Boolean);
begin
inherited Draw(AGraphics, ADrawText, ADrawBackGround, ADrawBorder);
with AGraphics do
begin
Canvas.Line(Left,Top, Left + Width,Left + Height);
Canvas.Line(Left,Top + Height,Left + Width,Top);
end;
Ok, in this way I can get a cross in every cell.
The only difference is that lazarus needs integer to be passed to Canvas.Line.
inherited Draw(AGraphics, ADrawText, ADrawBackGround, ADrawBorder);
with AGraphics do
begin
Canvas.Line(Trunc(Left),Trunc(Top), Trunc(Left + Width),Trunc(Top + Height));
Canvas.Line(Trunc(Left),Trunc(Top + Height),Trunc(Left + Width),Trunc(Top));
end;
I will work on it.
Thank you.