首页 > 解决方案 > TStringGrid中的Delphi多色值

问题描述

我希望 TStringGrid 表中的货币值有不同的颜色小数。怎么能这样做?

在此处输入图像描述

标签: delphidelphi-7

解决方案


您需要通过实现OnDrawCell处理程序自己绘制单元格。

像这样的东西:

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  Grid: TStringGrid;
  S: string;
  Val: Double;
  FracVal, IntVal: Integer;
  FracStr, IntStr: string;
  IntW, FracW, W, H: Integer;
  Padding: Integer;
const
  PowersOfTen: array[0..8] of Integer =
    (
      1,
      10,
      100,
      1000,
      10000,
      100000,
      1000000,
      10000000,
      100000000
    );
  Decimals = 2;
  BgColor = clWhite;
  IntColor = clBlack;
  FracColor = clRed;
begin

  Grid := Sender as TStringGrid;

  if (ACol < Grid.FixedCols) or (ARow < Grid.FixedRows) then
    Exit;

  Grid.Canvas.Brush.Color := BgColor;
  Grid.Canvas.FillRect(Rect);

  S := Grid.Cells[ACol, ARow];
  Padding := Grid.Canvas.TextWidth('0') div 2;

  if not TryStrToFloat(S, Val) or not InRange(Val, Integer.MinValue, Integer.MaxValue) then
  begin
    Grid.Canvas.TextRect(Rect, S, [tfSingleLine, tfVerticalCenter, tfLeft]);
    Exit;
  end;

  IntVal := Trunc(Val);
  IntStr := IntVal.ToString;
  if Decimals > 0 then
    IntStr := IntStr + FormatSettings.DecimalSeparator;
  IntW := Grid.Canvas.TextWidth(IntStr);
  FracVal := Round(Frac(Abs(Val)) * PowersOfTen[Decimals]);
  FracStr := FracVal.ToString.PadRight(Decimals, '0');
  if Decimals = 0 then
    FracStr := '';
  FracW := Grid.Canvas.TextWidth(FracStr);
  W := IntW + FracW;
  H := Grid.Canvas.TextHeight(IntStr);

  if W >= Grid.ColWidths[ACol] - 2*Padding then
  begin
    S := '###';
    Grid.Canvas.TextRect(Rect, S, [tfSingleLine, tfVerticalCenter, tfRight]);
  end
  else
  begin
    Grid.Canvas.Font.Color := IntColor;
    Grid.Canvas.TextOut(Rect.Right - Padding - W,
      Rect.Top + Rect.Height div 2 - H div 2, IntStr);
    Grid.Canvas.Font.Color := FracColor;
    Grid.Canvas.TextOut(Rect.Right - Padding - FracW,
      Rect.Top + Rect.Height div 2 - H div 2, FracStr);
  end;

end;

此代码将按原样写入左对齐的非数字数据。对于数字数据,它将绘制具有固定小数位数的值。您可以选择小数 (0..8),以及整数和小数部分的颜色。如果数字不适合其单元格,则会显示###。

带有文本和数字的网格屏幕截图。

我还没有完全测试代码。我会把它留给你作为练习。

更新:对不起,我忘记你使用的是 Delphi 7。这意味着你需要替换IntVal.ToStringIntToStr(IntVal)等等。


推荐阅读