【问题标题】:delphi : how can I change color of a cell in string griddelphi:如何更改字符串网格中单元格的颜色
【发布时间】:2011-10-05 19:11:04
【问题描述】:

我想在 delphi 中更改字符串网格中单元格的背景颜色(不是字体)。

只有一个单元格,而不是一行或一列。

我可以吗?


RRUZ :您的程序正确且有效,但在我的程序中不起作用。

我的程序:

x 是一个全局整数数组

procedure TF_avalie_salon.StringGrid1DrawCell(Sender: TObject; ACol,
    ARow: Integer; Rect: TRect; State: TGridDrawState);
    var   S: string;
begin
    S := StringGrid1.Cells[ACol, ARow];
    StringGrid1.Canvas.FillRect(Rect);
    SetTextAlign(StringGrid1.Canvas.Handle, TA_CENTER);
    StringGrid1.Canvas.TextRect(Rect,Rect.Left + (Rect.Right - Rect.Left) div 2, Rect.Top + 2, S);
    if (ARow<>0 )AND(acol<>0)AND(gridclick=true) then
    begin
        try
          gridclick:=false;
          x[acol+((strtoint(Edit_hafte.Text)-1)*7),arow]:=strtoint(StringGrid1.Cells[ACol, ARow]);
        except
          x[acol+((strtoint(Edit_hafte.Text)-1)*7),arow]:=0;
          StringGrid1.Cells[acol,arow]:='0';
          with TStringGrid(Sender) do
          begin
            Canvas.Brush.Color := clGreen;
            Canvas.FillRect(Rect);
            Canvas.TextOut(Rect.Left+2,Rect.Top+2,Cells[ACol, ARow]);
          end;
        end;
    end;
end;

当我在下面的代码中使用 Canvas.Brush.Color 时,Canvas.Brush.Color 不起作用。如果我在下面的代码中处于非活动状态,我可以更改单元格的颜色。但我两者都需要。

    S := StringGrid1.Cells[ACol, ARow];
    StringGrid1.Canvas.FillRect(Rect);
    SetTextAlign(StringGrid1.Canvas.Handle, TA_CENTER);
    StringGrid1.Canvas.TextRect(Rect,Rect.Left + (Rect.Right - Rect.Left) div 2, Rect.Top + 2, S);

【问题讨论】:

  • 只有在异常情况下才会执行使单元格变为绿色的代码,这几乎只能在 StrToInt 函数中执行。这是故意的吗?
  • 是的,andreas,我想在出现问题时更改单元格颜色。
  • 管理员或版主:我可以再问一次这个问题(完成和清除)
  • 这是重复的,stackoverflow中有很多关于customdraw的问题。绘制单元格或文本的工作方式相同。您只需要使用正确的属性。

标签: delphi background-color tstringgrid


【解决方案1】:
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
i:integer;  
begin
  with Sender as TStringGrid do
    begin
        Canvas.FillRect(Rect);
        DrawText (Canvas.Handle,
            PChar(Cells[ACol, ARow]),
            Length(Cells[ACol, ARow]),
            Rect, DT_WORDBREAK or DT_EXPANDTABS or DT_CENTER);
    end;
    for i:=2 to  StringGrid1.RowCount - 1 do
    if StringGrid1.Cells[3,i]='' then
      begin
        StringGrid1.Canvas.Brush.Color:=clRed;
          if ((ACol=3)and(ARow=i)) then
            begin
              StringGrid1.Canvas.FillRect(Rect);

            end;
      end;


end;

【讨论】:

  • 为什么要使用Sender as TStringGrid 演员表以及对StringGrid1 的直接引用。您是否打算将其作为一个独立的过程,而不是包含StringGrid1 的形式的方法,如果是独立的,您如何设想它实际上会被调用?
  • 也许您可能想解释为什么您认为此代码有效和/或原始帖子中缺少或不正确的内容...
  • 代码的第一部分设置单元格的颜色,并将文本居中对齐。代码的第三部分设置满足条件时某个单元格的颜色。在这段代码中,改变单元格颜色的条件是检查是否为空值,如果单元格中为“空”,则用红色字符突出显示。
  • 这些程序是专门为客户使用而编写的。如果用户没有正确输入数据或根本没有输入任何内容,则单元格将颜色变为红色。这部分代码检查空值,即列中的最后一个单元格。
  • Sender as StringGrid 被使​​用,因为这个过程继承了动态 StringGrid,当使用 fastreport 生成报告时
【解决方案2】:

我使用了这些代码,翻译成 C++。有两个具体的注释,那我贴代码吧。

  1. 在“StringGrid1”中,属性“DefaultDrawing”必须为 FALSE 才能正常工作。

  2. “Canvas”对象必须是完全限定的:即。 StringGrid1->Canvas->Font->Color =clBlack.

代码:

void __fastcall TForm3::StringGrid1DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect,
      TGridDrawState State)
{
UnicodeString   uStr = "Hello";
int     k, l;
char    cc[100];


if(TRUE)
    {
    if((ACol <= 1) || (ARow <= 1))
        {
        StringGrid1->Canvas->Font->Color = clBlack;
        StringGrid1->Canvas->Brush->Color = clBtnFace;
        if(ACol == 0)
            {
            if(ARow > 1)
                {
                sprintf( cc, " %5.1f", rowLabels[ARow - 2]);
                uStr = cc;
                StringGrid1->Canvas->TextRect( Rect, Rect.left+2, Rect.top+2, uStr);
                StringGrid1->Canvas->FrameRect(Rect);
                }
            }
        if(ARow == 0)
            {
            if(ACol > 1)
                {
                sprintf( cc, " %5.1f", colLabels[ACol - 2]);
                uStr = cc;
                StringGrid1->Canvas->TextRect( Rect, Rect.left+2, Rect.top+2, uStr);
                StringGrid1->Canvas->FrameRect(Rect);
                }
            }
        }
    else
        {
        switch (ACol%2)
            {
            case 0:
                {
                StringGrid1->Canvas->Font->Color = clRed;
                StringGrid1->Canvas->Brush->Color = 0x00E1FFF9;
                break;
                }
            case 1:
                {
                StringGrid1->Canvas->Font->Color = clBlue;
                StringGrid1->Canvas->Brush->Color = 0x00FFEBDF;
                break;
                }
            }
        StringGrid1->Canvas->TextRect( Rect, Rect.left+2, Rect.top+2, uStr);
        StringGrid1->Canvas->FrameRect(Rect);
        }
    }
}

【讨论】:

    【解决方案3】:

    Rafael 链接包含您需要的所有内容,使用 OnDrawCell 事件是绘制 StrignGrid 单元格的方法。检查此示例,它仅绘制特定单元格的背景。

    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;  Rect: TRect; State: TGridDrawState);
    begin
      if (ACol = 3) and (ARow = 2) then
        with TStringGrid(Sender) do
        begin
          //paint the background Green
          Canvas.Brush.Color := clGreen;
          Canvas.FillRect(Rect);
          Canvas.TextOut(Rect.Left+2,Rect.Top+2,Cells[ACol, ARow]);
        end;
    end;
    

    【讨论】:

    • 谢谢 ,,, 它可以单独工作,但不能在我的程序中使用。请在我的问题正文中检查我的程序。谢谢。
    • 你是什么意思哪个不起作用?您是否尝试在设置背景颜色 (Canvas.Brush.Color := clGreen;) 的行中设置断点以检查应用程序是否达到该点?
    • RUUZ:是的,我做了一个断点,它可以到达。我想我不能使用它,因为您的代码是正确的并且它来自应用程序。我不知道该怎么办。
    • 这与我的想法或您的想法无关。它是一个不到 15 行的简单代码,我说它不能一起工作,但它们都可以单独工作。现在,如果你能帮上忙,我会非常感激你,但其他没有帮助的 cmets 是垃圾邮件。
    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    相关资源
    最近更新 更多