I'm using the following code in the CustomCellDraw event of DBAdvGrid(TMS) to increase row height.
procedure TForm1.DBAdvGrid1CustomCellDraw(Sender: TObject; Canvas: TCanvas;
ACol, ARow: Integer; AState: TGridDrawState; ARect: TRect; Printing: Boolean);
begin
DBAdvGrid1.RowHeights[ARow]:=120;
end;
How do I make it avoid increasing row 0, which is the 1st row in the Grid, containing column names/headers? - I'd like that row to remain untouched while all the rest should get resized via the above code. Basically it should ignore row index 0 and start from row index 1
It would be like this:
procedure TForm1.DBAdvGrid1CustomCellDraw(Sender: TObject; Canvas: TCanvas;
ACol, ARow: Integer; AState: TGridDrawState; ARect: TRect; Printing: Boolean);
begin
if ARow > 0 then
DBAdvGrid1.RowHeights[ARow] := 120;
end;
But do not modify row heights from a drawing event. Such event is triggered frequently, and is used exclusively for content painting, not for adjusting content size. What's worse, if you e.g. allowed row sizing and the user would try to setup row height, it would in turn trigger that event where you would change the height back, so you'd be fighting with the user.
Content sizing should be done earlier, as this example shows in the OnCustomCellSize event.
But for your aim I think it's enough to set DefaultRowHeight and FixedRowHeight properties with no additional code.
Related
Is it possible to Word Wrap DBgrid Cell (height) in Delphi (xe) ?
I have a dbgrid with multiple columns with a fixed Column width and some columuns has up to 100char and I need them to fit the appropriate Cell without changing the Column width.
Any clue how to do it ?
Thanks.
You'll need to make it ownerdraw, and in the OnDrawCell event put the code to fill in the cells:
procedure TForm4.Grid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
Grid1.Canvas.TextRect(Rect, Rect.Left+1, Rect.Top+1, WrapText(Grid1.Cells[ACol,ARow], 40));
end;
I have an 8 x 16 DrawGrid in Delphi XE5 that I would like to randomly fill with nine images I've stored in C:\Users\Sean Ewing\Documents\My Documents\Delphi Tutorials\Other\Math-O-Sphere\Win32\Debug\img. I'm currently trying to get one image to load to make sure I'm doing it correctly. Here is the code I've used to do this:
procedure TForm1.grdPlayFieldDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
spherePlus: TBitmap;
begin
spherePlus.LoadFromFile(ExtractFilePath(Application.ExeName) + '\img\Sphere +1.bmp');
grdPlayField.Canvas.Draw(0, 0, spherePlus);
end;
The code compiles fine, and based on what I've read in the Embarcadero wiki this is correct, but I get an error at runtime when it's time to load the DrawGgrid. Where did I go wrong?
You need to first create the bitmap before you can use it:
procedure TForm1.grdPlayFieldDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
spherePlus: TBitmap;
begin
spherePlus := TBitmap.Create;
try
spherePlus.LoadFromFile(ExtractFilePath(Application.ExeName) +
'\img\Sphere +1.bmp');
grdPlayField.Canvas.Draw(0, 0, spherePlus);
finally
spherePlus.Free;
end;
end;
The other thing you should be aware of is that the Rect parameter you receive in the event is the area that needs to be painted, so you'll want to use Canvas.StretchDraw and pass it that rectangle. It won't help with the current issue, but you'll need it when you move to the next step. You can identify the exact cell that's being drawn with the ACol and ARow parameters, so you can use that information to load a specific image for a column, for instance, or to output text for a column or row.
// Load specific image for the cell passed in ACol and ARow,
// and then draw it to the appropriate area using the Rect provided.
grdPlayField.Canvas.StretchDraw(Rect, spherePlus);
I am using Developer Express components - TdxDBgrid as Grid and TdxMemData as dataset.
There are around 10 columns displayed in grid.
For the second column, I am trying to change starting point where column value displayed. I am trying to do it using ACanvas.TextRect. But the changes are not getting affected. Anybody having idea how to change starting position of data in Column for any grid.
thanks
I'm not sure if what you're asking is how to shift the x-position where the text starts, but if it is, try something like this:
procedure TForm1.dxDBGrid1Column2CustomDrawCell(Sender: TObject;
ACanvas: TCanvas; ARect: TRect; ANode: TdxTreeListNode;
AColumn: TdxTreeListColumn; ASelected, AFocused, ANewItemRow: Boolean;
var AText: String; var AColor: TColor; AFont: TFont;
var AAlignment: TAlignment; var ADone: Boolean);
var
XOffset : Integer;
begin
XOffset := 20;
ACanvas.FillRect(ARect);
ACanvas.TextOut(ARect.Left + XOffset, ARect.Top, AText);
ADone := True;
end;
Obviously that doesn't deal with details like how to draw selected and focused columns, etc, but you should get the idea and you can look at the DevEx source for those.
Previously with the default DBGrid I could alter the value of a cell without altering the data in a database with the following code.
procedure TEMRForm.DBGridCDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if Column.FieldName = 'START_DATE' then
begin
DBGridC.Canvas.FillRect(Rect);
DBGridC.Canvas.TextOut(Rect.Left+2,Rect.Top+2,Column.Field.Text + ' *');
end;
end;
Which worked great, but I am having trouble implementing this same kind of functionality on a cxgrid. Here is my current code which shows no indication of the cell value being changed.
procedure TEMRForm.cxGridCDBTableView1CustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
var
ARect: Trect;
begin
ARect := AViewInfo.Bounds;
if AViewInfo.Item.Caption = 'Start Date' then
begin
ACanvas.FillRect(ARect);
ACanvas.TextOut(ARect.Left+2,ARect.Top+2,TableC.FieldByName('START_DATE').AsString+' *');
end;
end;
I think the reason why you don't see the drawning done in cxGridCDBTableView1CustomDrawCell() is because you don't set the ADone parameter to true - thus the default painting will "cancel" (overpaint) your's.
However, I think the right way to achieve what youre after is to use column's events OnGetDisplayText and OnGetContentStyle (the later event is subproperty of Styles, ie Column.Styles.OnGetContentStyle).
I have a TStringGrid with several rows in which I implemented some kind of 'read-only' row. More exactly, I don't allow the user to click the penultimate row. If the user clicks the last row nothing happens; the focus won't be moved to the cells of that row.
I have the code (in KeyDown) and everything works smooth. However, if the user clicks the top row and then uses the mouse wheel to scroll down, eventually the focus will move to the penultimate row. Any idea how to prevent this?
Well, you could override DoMouseWheelDown to achieve this.
function TMyStringGrid.DoMouseWheelDown(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
if Row<RowCount-2 then
//only allow wheel down if we are above the penultimate row
Result := inherited DoMouseWheelDown(Shift, MousePos)
else
Result := False;
end;
But how do you know that there isn't some other way to move the focus to the last row?
In fact a much better solution is to override SelectCell:
function TMyStringGrid.SelectCell(ACol, ARow: Longint): Boolean;
begin
Result := ARow<RowCount-1;
end;
When you do it this way you don't need any KeyDown code, and you don't need to override DoMouseWheelDown. All possible mechanisms to change the selected cell to the final row will be blocked by this.
As #TLama correctly points out, you don't need to sub-class TStringGrid to achieve this. You can use the OnSelectCell event:
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Longint;
var CanSelect: Boolean);
begin
CanSelect := ARow<(Sender as TStringGrid).RowCount-1;
end;
I solved this problem by putting this in the event OnMouseWheelUp:
procedure Tmainform.sgup(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
sg.RowCount := sg.RowCount + 1;
sg.RowCount := sg.RowCount - 1;
end;