有一个相当笨但却很直接的办法:自绘。可处理多个列。对于StringGrid和DBGrid同样适用。 示例代码:不改变控件属性,只是必要时不显示出来而已。处理了文字位置居中的问题。 procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); var sValue:string; iTextWidth,iTextheight,iLeft,iTop:integer; begin with TStringGrid(Sender) do begin sValue:=Cells[ACol,ARow]; if (ARow>1)and(Trim(Cells[ACol,ARow-1])=Trim(sValue)) then sValue:=''; iTextWidth:=Canvas.TextWidth(sValue); iTextheight:=Canvas.TextHeight(sValue); iLeft:=Rect.Left+(Rect.Right-Rect.Left-iTextWidth)div 2; iTop:=Rect.Top+(Rect.Bottom-Rect.Top-iTextheight)div 2; if iLeft<Rect.Left then iLeft:=Rect.Left; if iTop<Rect.Top then iTop:=Rect.Top; Canvas.FillRect(Rect); Canvas.TextRect(Rect,iLeft,iTop,sValue); end; end; 由于是自绘,所以控件属性由用户或代码改变时需要更新。 procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String); begin StringGrid1.Invalidate; end; 怎么样,解决了吧?
示例代码:不改变控件属性,只是必要时不显示出来而已。处理了文字位置居中的问题。
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
sValue:string;
iTextWidth,iTextheight,iLeft,iTop:integer;
begin
with TStringGrid(Sender) do
begin
sValue:=Cells[ACol,ARow];
if (ARow>1)and(Trim(Cells[ACol,ARow-1])=Trim(sValue)) then
sValue:='';
iTextWidth:=Canvas.TextWidth(sValue);
iTextheight:=Canvas.TextHeight(sValue);
iLeft:=Rect.Left+(Rect.Right-Rect.Left-iTextWidth)div 2;
iTop:=Rect.Top+(Rect.Bottom-Rect.Top-iTextheight)div 2;
if iLeft<Rect.Left then
iLeft:=Rect.Left;
if iTop<Rect.Top then
iTop:=Rect.Top;
Canvas.FillRect(Rect);
Canvas.TextRect(Rect,iLeft,iTop,sValue);
end;
end;
由于是自绘,所以控件属性由用户或代码改变时需要更新。
procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol,
ARow: Integer; const Value: String);
begin
StringGrid1.Invalidate;
end;
怎么样,解决了吧?
商榷