|
|
 |
 |
|
|
 |
 |
|
Join the Discussion
|
"Post your views, comments, questions and doubts to this article."
Discuss!
|
|
 |
 |
|
|
 |
 |
 |
Merged cells
In the sample code, I have made a subheading for each third data row. When I need to present data grouped into subcategories, I often want the subheadings to flow across cell boundaries. One solution for this to happen is to merge all the columns into one wide cell. The way I have found to this is shown in the last listing.
As you will see that's no hard at all. Before we start to draw, we modify our cell Rect to include the complete width of the grid. This will result in a fixed sub header, unaffected by horizontal scrolling. Using the same approach to merge any two columns is not that hard. Use GetCellRect( ) method of the grid to get the boundaries for the first and the last you want to merge. Then calculate the merged cell Rect from them.
procedure TfrmMain.gridOwnerDrawDrawCell
(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
//Make some text to display in cell:
function GetText(ACol, ARow: integer): string;
begin
[...]
end;
var
txtRect: TRect;
btnRect: TRect;
btnState: integer;
tmpstr, str: string;
kodewidth: integer;
tmpRect: TRect;
focusRect: TRect;
begin
//If header is to be drawn:
if ARow = 0 then
begin
[...]
end
//If subheader is to be drawn:
else if ARow mod 4 = 1 then
begin
//Merging cell:
rect.right := gridOwnerDraw.width;
rect.Left := 0;
//Setting canvas properties and erasing old cellcontent:
gridOwnerDraw.Canvas.Brush.Color := clWindow;
gridOwnerDraw.Canvas.Brush.Style := bsSolid;
gridOwnerDraw.Canvas.Pen.Style := psClear;
gridOwnerDraw.Canvas.FillRect(rect);
//Textposition:
txtRect := Rect;
txtRect.Left := Rect.left + TXT_MARG.x;
//Drawing text:
str := GetText(ACol, ARow);
gridOwnerDraw.Canvas.Font.Color := clInfoText; //clHighlightText;
gridOwnerDraw.Canvas.Font.Name := gridOwnerDraw.Font.Name;
gridOwnerDraw.Canvas.Font.Size := gridOwnerDraw.Font.Size;
gridOwnerDraw.Canvas.Font.Style := [fsBold];
DrawText(gridOwnerDraw.canvas.Handle, PChar(str),
length(str), txtRect, DT_SINGLELINE or DT_LEFT or
DT_VCENTER or DT_END_ELLIPSIS);
//Drawing focusrect:
if gdSelected in State then
with gridOwnerDraw.canvas do begin
Pen.Style := psInsideFrame;
Pen.Color := clBtnShadow;
Polyline([Point(Rect.left, Rect.Top),
Point(Rect.right-1, Rect.Top)]);
Polyline([Point(Rect.left, Rect.Bottom-1),
Point(Rect.right-1, Rect.Bottom-1)]);
if ACol = 0 then
Polyline([Point(Rect.left, Rect.Top),
Point(Rect.left, Rect.Bottom-1)])
else if ACol = gridOwnerDraw.ColCount - 1 then
Polyline([Point(Rect.right-1, Rect.Top),
Point(Rect.right-1, Rect.Bottom-1)]);
end
else
begin
//If not selected, draw a line under subheading:
gridOwnerDraw.Canvas.Pen.Style := psInsideFrame;
gridOwnerDraw.Canvas.Pen.Color := clBlack;
gridOwnerDraw.Canvas.Polyline
([Point(rect.Left + TXT_MARG.x, rect.bottom-1),
Point(rect.right, rect.bottom-1)]);
end
end
//For the rest of the rows:
else
begin
[...]
end;
end;
|
The goal for this article was to give some hints on how you can make the standard grids form Delphi look good. We have seen that all it takes is some creativity and some playing with the grids canvas. Combining this with a well designed data structure containing your data, you can have a professional look without spending all your money on third-party components suite. I have used a TDrawGrid to present data into hierarchical lists, grouped lists (as shown here) and even nested grids. Download the sample application, and see if this is something that you can use.
That's it
Please download the sample project, and of course post any questions to the Delphi Programming Forum.
First page > How to fix-up the column headers > Page 1, 2, 3
|