【问题标题】:colour a stringgrid column depending on columnname text根据列名文本为 stringgrid 列着色
【发布时间】:2012-05-18 22:46:08
【问题描述】:

我正在这样做:

procedure TForm1.BitBtn1Click(Sender: TObject);
 var dtStart: TDateTime;
  I: Integer;
begin
  dtStart := DateTimePicker1.Date;
  for I := 0 to 7 do
    AdvStringGrid1.Cells[I+1, 0] := uppercase(FormatDateTime('DD/MM/YYYY     DDD', dtStart + I));
   end;

有没有办法在(示例)星期日 (SUN) 出现时为列着色?我希望 SUN 栏(一直向下)以与其他栏不同的颜色显示。

【问题讨论】:

    标签: delphi-7 delphi-xe2 delphi-xe tstringgrid ownerdrawn


    【解决方案1】:

    您可以通过使用OnDrawCell 事件来做到这一点(不要DefaultDraw 设置为False)。这是一个带有常规 TStringGrid 的示例:

    // Sample to populate the cells with the days of the week
    procedure TForm1.FormShow(Sender: TObject);
    var
      r, c: Integer;
    begin
      StringGrid1.ColCount := 8;  // Ignore fixed column and row for this example
      StringGrid1.RowCount := 8;
    
      for c := 1 to StringGrid1.ColCount - 1 do
        for r := 1 to StringGrid1.RowCount - 1 do
          StringGrid1.Cells[c, r] := FormatSettings.ShortDayNames[c];
    end;
    
    // Assign this to the StringGrid's OnDrawCell using the Object Inspector 
    // Events tab.
    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    var
      CellText: string;
    begin
      if (ARow > 0) and (ACol > 0) then
      begin
        CellText := StringGrid1.Cells[ACol, ARow];
        if Pos('Sun', CellText) > 0 then
        begin
          StringGrid1.Canvas.Brush.Color := clRed;
          StringGrid1.Canvas.FillRect(Rect);
        end
        else
          StringGrid1.Canvas.Brush.Color := clWindow;
      end;
    
      // The '+ 4' is from the VCL; it's hard-coded when themes are enabled. 
      // You should probably check the grid's DrawingStyle to see if it's 
      // gdsThemed, and adjust as needed. I leave that as an exercise for you.
      StringGrid1.Canvas.TextOut(Rect.Left + 4, Rect.Top + 4, CellText);
    end;
    

    上面确切代码的示例输出:

    这是第二个示例,它可以准确地输出您想要的内容(除了我没有将 SUN 转换为大写字母):

    procedure TForm1.FormShow(Sender: TObject);
    var
      r, c: Integer;
    begin
      StringGrid1.DefaultColWidth := 100;
      StringGrid1.ColCount := 8;
      StringGrid1.RowCount := 8;
    
      for c := 1 to StringGrid1.ColCount - 1 do
        for r := 1 to StringGrid1.RowCount - 1 do
          StringGrid1.Cells[c, r] := FormatDateTime('mm/dd/yyyy ddd', 
                                                    Date() + c + r - 1);
    end;
    
    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    var
      CellText: string;
    begin
      if (ARow > 0) and (ACol > 0) then
      begin
        CellText := StringGrid1.Cells[ACol, ARow];
        if Pos('Sun', CellText) > 0 then
          StringGrid1.Canvas.Brush.Color := clRed
        else
          StringGrid1.Canvas.Brush.Color := clWindow;
        StringGrid1.Canvas.FillRect(Rect);
      end;
      StringGrid1.Canvas.TextOut(Rect.Left + 4, Rect.Top + 4, CellText);
    end;
    

    这是匹配第二个样本的捕获:

    【讨论】:

    • 它在我的情况下不起作用。我也有日期。这也只为活动单元格着色。如果列名中存在 SUN 一词,我想为整个列(包括固定单元格)着色。
    • 你的这段代码也把我的单元格的内容清空了,所以我什么都看不到......
    • 嗯,不,它没有。 :) 我会添加一个屏幕截图。它还将为包含文本Sun(通过在上面的代码中使用Pos 找到)的任何单元格着色,而不仅仅是活动单元格。您必须调整代码以满足您的确切需求;我发布的是如何做到这一点的一个例子,但这只是一个起点。 :)
    • 我有您在列名(固定单元格)中显示的日期。你的这个版本搜索活动单元格并且不检测列名中的字符。就像我说的,我希望程序检测列名中的单词 SUN 并从上到下为该列着色。我没有用日期填充活动单元格。然而,对我来说,第一个代码示例用颜色填充了一个单元格并擦​​除了我的文本。稍后会测试这个新版本,但从外观上看它与第一个版本基本相同......
    • 我认为我们在这里沟通失败。 :) 您询问了有关为列着色的问题,这就是我所展示的。现在您似乎在询问是否为 列标题 着色,这是相似的(只需删除对删除固定单元格的 Col > 0 and Row > 0 的检查,并相应地调整代码;将 Pos 更改为只需检查要测试SUN 的固定行或列中的内容)。您想为整个列中的单元格着色,还是只为列标题着色?你能澄清一下是什么吗?谢谢。 :)
    【解决方案2】:

    使用 DrawCell 过程是可行的方法。此示例处理带有“Sun”的列可能位于任何列中的可能性。将 DefaultDrawing 保留为默认值 - true。

    
        procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
             Rect: TRect; State: TGridDrawState);
        begin
          with Sender as TStringGrid do
           if Pos('Sun', Cells[ACol, 0])>0 then begin
             Canvas.Brush.Color := clRed;
             Canvas.FillRect(Rect);
             Canvas.Font.Color := clwhite;
             Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]);
           end;
          end;
        

    【讨论】:

    • 抱歉回复晚了……我出去了几天。当我使用您的代码时,字符串网格的行为非常奇怪。我在 2 行中的列标题名称突然变为 1,并且在第二行中的部分被部分切断。只有当我单击它下面的单元格时,整个列才会被着色。我不知道如何在这里发布图片,所以我可以给你看......
    • 你如何在这里发布照片?除了我原来的问题外,我没有那个选项......“帮助”根本没有帮助......
    • 我的错 - 我没有意识到您使用的是第 3 方组件。我认为使用 AdvStringGrid 您可以非常轻松地设置颜色。你不需要使用 DrawCell 程序。不能帮助图片:(
    • 这些字符串网格应该很简单,但是当你尝试做一些简单的事情时,结果却是一场噩梦...... :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 2012-10-05
    • 2016-03-03
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 2015-10-26
    相关资源
    最近更新 更多