近日在DBGRID應用中涉及到需要對特殊數據進行顯式的顯示,於是設定指定單元格顏色、指定單元格根據數據顯示向上或向下方向箭頭。發現畫箭頭的和顏色指定的代碼有一定的通用性,於是單獨寫出來,並且儘量優化了代碼,以便於增強通用性。先拿出來以便分享。效果如下圖所示:
//圖片暫時沒辦法上傳,似乎csdn後臺目前有問題,稍後補上
整段代碼如下[你可以根據自己的需要,修改相應的參數即可]:
procedure TfrmClientCenter.DBGrid2DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
var
tx,tn:Integer;
begin
//設定"上漲"的記錄,指定特定單元格顏色
with Clientdataset do
begin
if (FieldByName('markup').AsString<>'') and (FieldByName('markup').AsInteger>0) then
begin
if (Column.Field=FieldByName('bargain')) then //是特定的字段則顯示指定顏色
begin
DBGrid2.Canvas.Font.Color:=clRed; //指定紅色字體
DBGrid2.Canvas.TextOut(Rect.Left,Rect.Top,Fieldbyname('bargain').AsString);
end;
if (Column.Field=FieldByName('buy1')) then
begin
DBGrid2.Canvas.Font.Color:=clGreen; //指定綠色字體
DBGrid2.Canvas.TextOut(Rect.Left,Rect.Top,Fieldbyname('buy1').AsString);
end;
if (Column.Field=FieldByName('high')) then
begin
DBGrid2.Canvas.Font.Color:=clRed;
DBGrid2.Canvas.TextOut(Rect.Left,Rect.Top,Fieldbyname('high').AsString);
end;
if (Column.Field=FieldByName('low')) then
begin
DBGrid2.Canvas.Font.Color:=clRed;
DBGrid2.Canvas.TextOut(Rect.Left,Rect.Top,Fieldbyname('low').AsString);
end;
if (Column.Field=FieldByName('aver')) then
begin
DBGrid2.Canvas.Font.Color:=clRed;
DBGrid2.Canvas.TextOut(Rect.Left,Rect.Top,Fieldbyname('aver').AsString);
end;
if (Column.Field=FieldByName('tempmarkup')) then
begin
DBGrid2.Canvas.Font.Color:=clRed;
DBGrid2.Canvas.TextOut(Rect.Left,Rect.Top,Fieldbyname('tempmarkup').AsString);
end;
end;
end;
//畫"漲/跌"箭頭
{由於此處畫箭頭是根據"markup"的值爲正負來確定的,所以畫箭頭的時候不能顯示負號"-",於是我用了另一個字段'tempmarkup"來保存並用於顯示無符號數值"markup"(前面已經處理了tempmarkup:=abs(markup)的動作),而"markup"本身在DBGRID中則不顯示即可}
if Trim(Column.Field.DataSet.FieldByName('markup').AsString) <>'' then
begin
tx:=length(Column.Field.DataSet.Fields.FieldByName('tempmarkup').AsString); //數據實際長度
tn:=(tx+1)*5; //換算數據的顯示長度{此段很重要,直接影響到箭頭和數據的相對位置}
TDBGrid(Sender).DefaultDrawColumnCell(Rect,DataCol,Column,State);
if (Column.FieldName='tempmarkup') then
begin
with TDBGrid(Sender).Canvas do
begin
//正數畫向上箭頭
if Column.Field.DataSet.FieldByName('markup').AsInteger>0 then
begin
Pen.Color :=clRed ; //指定畫箭頭的顏色爲紅色
drawArrow(TDBGrid(Sender).Canvas,'up',Rect.Right-tx-tn-2,Rect.Bottom-6,Rect.Right-tx-tn-2,Rect.Top+2,5);
end;
//負數畫向下箭頭
if Column.Field.DataSet.FieldByName('markup').AsInteger<0 then
begin
Pen.Color :=Column.Font.Color; //指定畫箭頭的顏色爲字段本身的顏色
drawArrow(TDBGrid(Sender).Canvas,'down',Rect.Right-tx-tn-2,Rect.Bottom-6,Rect.Right-tx-tn-2,Rect.Top+2,5);
end;
end;
end;
end;
end;
{說明: drawArrow(TDBGrid(Sender).Canvas,'up',Rect.Right-tx-tn-2,Rect.Bottom-6,Rect.Right-tx-tn-2,Rect.Top+2,5); 中用Rect.Right-tx-tn-2,是因爲我的數據字段靠右對齊的,其中"-2"就是讓箭頭距離數據的距離,想要加大箭頭和數據的距離就把2變大即可;當然如果你的數據是靠左對齊的,那麼這裏所有的減號,就要變成加號,變成Rect.Left+tx+tn+2。}
//畫箭頭函數體 {可以用不同的參數直接調用,無須更改}
procedure TfrmClientCenter.drawArrow(acanvas:Tcanvas;updown:string;x0,y0,x1,y1:Integer;arrowlen:real);
var
xa, ya, xb, yb: real;
d: real;
begin
acanvas.pen.style := pssolid;
//acanvas.pen.color := clRed ;
//畫直線
acanvas.moveto(x0,y0); //箭頭的起點
acanvas.lineto(x1,y1); //箭頭的終點
//畫箭頭
if updown='up' then //向上箭頭
begin
d := sqrt((y1 - y0) * (y1 - y0) + (x1 - x0) * (x1 - x0));
if d > 0 then
begin
xa := x1 + arrowlen * ((x0 - x1) + (y0 - y1) / 2) / d;
ya := y1 + arrowlen * ((y0 - y1) - (x0 - x1) / 2) / d;
xb := x1 + arrowlen * ((x0 - x1) - (y0 - y1) / 2) / d;
yb := y1 + arrowlen * ((y0 - y1) + (x0 - x1) / 2) / d;
acanvas.moveto(x1,y1);
acanvas.lineto(trunc(xa), trunc(ya));
acanvas.moveto(x1,y1);
acanvas.lineto(trunc(xb), trunc(yb));
end;
end;
if updown='down' then //向下箭頭
begin
d := sqrt((y0 - y1) * (y0 - y1) + (x0 - x1) * (x0 - x1));
if d > 0 then
begin
xa := x0 - arrowlen * ((x0 - x1) + (y0 - y1) / 2) / d;
ya := y0 - arrowlen * ((y0 - y1) - (x0 - x1) / 2) / d;
xb := x0 - arrowlen * ((x0 - x1) - (y0 - y1) / 2) / d;
yb := y0 - arrowlen * ((y0 - y1) + (x0 - x1) / 2) / d;
acanvas.moveto(x0,y0);
acanvas.lineto(trunc(xa), trunc(ya));
acanvas.moveto(x0,y0);
acanvas.lineto(trunc(xb), trunc(yb));
end;
end;
end;