【问题标题】:Dynamic DBGrid Cell coloring动态 DBGrid 单元格着色
【发布时间】:2012-07-19 06:01:30
【问题描述】:

我正在使用来自 Jedi 组件组 (TJvDBGrid) 的 Delphi XE-2 和 DBGrid。现在,我发现在值已知的情况下定义单元格颜色非常容易,例如:

OnGetCellParams event: 
if DBGrid.Field.AsInteger = 0
then Background := clYellow;

但在我的情况下,用户可以定义什么值将具有什么颜色,存储在单独的表中。我的问题是,有没有办法通过查找单元格值是否分配了颜色来为单元格着色?

我将不胜感激任何关于此事的帮助或指导,谢谢。

【问题讨论】:

    标签: delphi


    【解决方案1】:

    最简单的方法可能是使用表单的OnCreate 来填充一个数组,然后在OnGetCellParams 事件中访问它。数组应包含尽可能多的项目,以及数组索引 0 的默认值,以防未分配颜色。 (下面是未经测试的现成代码!)

    type
      TForm1 = class(TForm)
        ...
        procedure FormCreate(Sender: TObject);
      private
        FColors: array of TColor;
      end;
    
    implementation
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      NumRows, i: Integer;
    begin
      // One row for each possible value for the integer column you're
      // trying to color the cell for (eg., if the table can hold a value
      // from 0-10, you need the same # of items in the array (array[0..10])
      NumRows := NumberOfPossibleValues;
      SetLength(FColors, NumberOfPossibleValues);
    
      // Pre-fill the array with the default clWindow color,
      // in case a custom color isn't assigned to a value
      // (for instance, the user doesn't set a color for a value
      // of 7).
      for i := 0 to High(FColors) do
        FColors[i] := clWindow;  
    
      // Assumes your color values are in a database called FieldColors,
      // in a datamodule called dmAppData, and that there's a
      // column named ColValue indicating the `Field.AsInteger`
      // value and the corresponding TColor stored as an integer.
      dmAppData.FieldColors.First;
      while not dmAppData.FieldColors.Eof do
      begin
        i := dmAppData.FieldColors.FieldByName('ColValue').AsInteger;
    
        // Might want to put a check here to make sure the value isn't
        // more than the number of items in the array!!!
        FColors[i] := TColor(dmAppData.FieldColors.FieldByName('Color').AsInteger);
        dmAppData.FieldColors.Next;
      end;
    end;
    

    在您的OnGetCellParams 活动中:

    Background := FColors[DBGrid.Field.AsInteger];
    

    您可能希望在 OnGetCellParams 中使用局部变量以确保您保持在数组范围内:

    Background := clWindow;
    i := DBGrid.Field.AsInteger;
    if (i > 0) and (i < Length(FColors)) then
      Background := FColors[i];
    

    更慢的方法是在OnGetCellParams 事件中为每一行执行Locate

    OnGetCellParams:

    Background := clWindow;
    if dmAppData.FieldColors.Locate('ColValue', DBGrid.Field.AsInteger, []) then
      Background := TColor(dmAppData.FieldColors.FieldByName('Color').AsInteger);
    

    【讨论】:

    • 谢谢,鉴于我的表将保存非常有限(很少)的数据量,我想我会选择“定位”选项。有趣的是,它在运行时提示“多步操作产生错误”。我肯定也会尝试“数组”方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 2011-08-07
    • 2013-01-09
    • 2011-08-19
    • 2016-05-08
    • 1970-01-01
    相关资源
    最近更新 更多