DBGridの背景色に一行置きに色をつけるには?

解決


マッキー  2007-11-27 20:32:37  No: 28684

いつも大変お世話になっています。
データベースから取得したデータをDBGridに表示させています。
件数や多く横に長いため、一行おきに背景色の色をつけたほうが見やすいのかなと思っています。(例  奇数行が  デフォルトの白。偶数行が灰色)
DBGrid自体にそういった機能はないようなのでコード化しないと
いけないようですが。。。。  どのように記述すればよいか
不明です。何かヒントでも頂ければと思います。
実現されているかたがいらっしゃいましたら
ご教授願います。


Ru  2007-11-27 20:39:14  No: 28685

OnDrawColumnCellイベント利用して出来ると思います。

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin

  //※TDataSet.RecNoプロパティでレコード位置取得できるかな?
  //(データベースによって出来なかった気もするけど・・・)
  if 条件 then
  begin
    DBGrid1.Canvas.Brush.Color := clMedGray;
  end;

  DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);

end;


KHE00221  2007-11-27 22:08:38  No: 28686

ARow があれば ARow mod 2 = 0 で 1行ずつの判定が可能かと思いますが
なぜか DrawCell の時は存在する ARow が DrawColunCell のときは消えています

procedure TCustomDBGrid.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);

 DrawColumnCell(ARect, ACol, DrawColumn, AState);

どかかにRowを示すプロパティ等があるのかもしれませんが、
ぱっと見分からなかったので・・・継承して逃げてみました

  TDBGridEx = class(TDBGrid)
  private
    FSaveRow : Integer;
    FSaveCol : Integer;
  public
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
  published
    property SaveRow : Integer  read FSaveRow;
    property SaveCol : Integer read FSaveCol;  //Colは必要ないけど
  end;

procedure Register;

implementation

procedure TDBGridEx.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
begin
    FSaveRow := ARow;
    FSaveCol := ACol;
    inherited;
end;

というふうに DBGrid を継承して DBGirdEx を作成して

if (SaveRow mod 2) = 0 then C := clRed else C := clBlue;
DBGridEx1.Canvas.Brush.Color := C;
DBGridEx1.DefaultDrawColumnCell(Rect,DataCol,Column,State);

としてやれば1行ずつ色を変えて表示する事が可能になります


マッキー  2007-11-27 23:34:57  No: 28687

Ru さん、KHE00221 さん、早速のご回答ありがとうございました。
継承という高度な方法は使用したことがないのですが、今回良いチャンスなので、KHE00221さんの方法で挑戦中ですが。。。2点質問です。

procedure Register;  というのはどのような意味なのでしょうか?
入力場所が悪いのか、コンパイルエラーがでます。
"Forwardまたはexternal宣言された"TDBGridEx.Register"がみつかりません。となります。implementationの上に記述しているのですが。。。。

もうひとつ。下記は、どこに記述したらよいのでしょうか?
DBGridExというクラスを作成したところまではなんとなく理解できるのですが。。。。  下記は、DBGridの  DBGridDrawColumnCell  に記述するのでしょうか?  よろしくお願い致します。

if (SaveRow mod 2) = 0 then C := clRed else C := clBlue;
DBGridEx1.Canvas.Brush.Color := C;
DBGridEx1.DefaultDrawColumnCell(Rect,DataCol,Column,State);


KHE00221  2007-11-28 00:32:31  No: 28688

ソース
----------------------------------------------------
unit DBGridEx;

interface

uses
  Windows, Classes, Grids, DBGrids;

type

  TDBGridEx = class(TDBGrid)
  private
    FSaveRow : Integer;
    FSaveCol : Integer;
  protected
  public
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
  published
    property SaveRow : Integer  read FSaveRow;
    property SaveCol : Integer read FSaveCol;
  end;

procedure Register;

implementation

procedure TDBGridEx.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
begin
    FSaveRow := ARow;
    FSaveCol := ACol;
    //継承元のDrawCellを実行する
    inherited;
end;

procedure Register;
begin
  //Componentパレットに TDBGridEx が登録される
  RegisterComponents('Component', [TDBGridEx]);
end;

end.

------------------------------------------------

そして

procedure TForm1.DBGridEx1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var
    C : TColor;
begin

  if (SaveRow mod 2) = 0 then C := clRed else C := clBlue;
  DBGridEx1.Canvas.Brush.Color := C;
  DBGridEx1.DefaultDrawColumnCell(Rect,DataCol,Column,State);

end;


マッキー  2007-11-28 02:52:07  No: 28689

KHE00221さん、詳細なソースありがとうございます。
結論から言いますとまだできていません。
継承やクラスの概念が理解できていない為だと思います。すみません。
もう少し教えてくださいませ。
ソース部分のDBGridExという、unit句を追加。
(DBGridEx.pasファイル作成)
※不勉強なもので、継承はtype句で定義するものだと思っていました。

ここまでは、コンパイルは問題なく通ります。
この後、"そして"の部分はどこに記述するのでしょうか?
DBGridを使用しているメインのpasファイルに記述しても
"DBGridEx1DrawColumnCell"が未定義と表示されます。
implementation  句に  uses DBGridEx;  ←は追加しています。
"DBGridEx.DrawColumnCell"としたり"DBGridEx1.DrawColumnCell"としても
同じエラーです。
DBGrid とどこで紐づくかもさっぱり理解できていない超初心者です。
申し訳ございませんが、再度教えて頂きますようお願いします。


Null  2007-11-28 04:10:48  No: 28690

横から御免なさい。

この様な物も、選択肢(解決策)の一つには成りませんか?。


http://www1.cncm.ne.jp/~ogawate/delphi/components/components.html


KHE00221  2007-11-28 05:39:59  No: 28691

そしての部分は DBGridEx の OnDrawColumnCell イベントです。

オブジェクトインスペクタのイベントの OnDrawColumnCell をダブルクリックすると

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin

end;

と自動的に作成されるので、ここを

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
    C : TColor;
begin

  if (SaveRow mod 2) = 0 then C := clRed else C := clBlue;
  DBGridEx1.Canvas.Brush.Color := C;
  DBGridEx1.DefaultDrawColumnCell(Rect,DataCol,Column,State);

end;

というふうに書き換えてください。


マッキー  2007-11-28 17:36:20  No: 28692

KHE00221さん  ありがとうございます。
まだダメです。(本当にすみません)
上記方法だと、"SaveRow"、"DBGridEx1"が未定義の識別子となり
コンパイルエラーになります。
そもそも、 DBGridEx の OnDrawColumnCell イベントがありません。
TForm1.DBGrid1DrawColumnCell はありますので、それに読み替えて
記述しました。
DBGridEx がオブジェクトインスペクタに表示されないのが問題なのでしょうか?何回もすみませんが、よろしくお願い致します。
Nullさん、情報ありがとうございました。
便利なコンポーネントのようですね。ダウンロードしましたので
後で使ってみたいと思います。
ありがとうございました。


KHE00221  2007-11-28 17:58:00  No: 28693

>DBGridEx がオブジェクトインスペクタに表示されないのが問題なのでしょうか

コンポーネントパレットに DBGridEx が登録され、フォームに DBGridEx を貼り付けている状態ですか?

DXGridEx をコンパイルしただけでは登録されませんよ


マッキー  2007-11-28 19:44:59  No: 28694

KHE00221  さん、色々とご説明ありがとうございまし。
>コンポーネントパレットに DBGridEx が登録され、フォームに DBGridEx を>貼り付けている状態ですか?

やっぱりよく理解していなかったようです。
コンポーネントとして取り込み、フォームに DBGridEx を貼り付けて
上記作業を行いましたら、一行おきに色がつきました。
ありがとうございました。
ちなみに、DBGridEx1.SaveRow  と明示しないとコンパイルエラーになりました。  ただ、グリッドの無いをクリックすると文字が白くなり空白になりました。  もう少し改善が必要と思います。。。。。
お手数をおかけしました、本当にありがとうございました。
Nullさん、早速試してみました。こちらもOKでした。
折角作ったのに、日の目を見ないのは淋しいですね。
結構需要はあると思いますが。。。  ありがとうございました。
ちなみに、Windows xp  + delphi7 + Oracle 8i で動作しました。


KHE00221  2007-11-29 18:31:41  No: 28695

編集中の背景の色も変更に対応版です

unit DBGridEx;

interface

uses
  Windows,SysUtils, Classes, Messages, Graphics, Controls, Grids, DBGrids;

type

  TMouseDown2Event = procedure(Sender:TObject;Row,Col:Integer) of Object;

  TDBGridEx = class(TDBGrid)
  private
    FSaveRow : Integer;
    FSaveCol : Integer;
    FMouseDown2Event : TMouseDown2Event;
  public
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
  published
    property SaveRow : Integer read FSaveRow;
    property SaveCol : Integer read FSaveCol;
    property InplaceEditor;
    property Row;
    property Col;
    property OnMouseDown2 : TMouseDown2Event read FMouseDown2Event write FMouseDown2Event;
  end;

procedure Register;

implementation

procedure TDBGridEx.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
begin
    FSaveRow := ARow;
    FSaveCol := ACol;
    inherited;
end;

procedure TDBGridEx.WMLButtonDown(var Message: TWMLButtonDown);
begin
    inherited;
    if Assigned(InplaceEditor) = True then
    begin
      if Assigned(FMouseDown2Event) = True then OnMouseDown2(Self,Row,Col);
    end;
    Exit;
end;

procedure Register;
begin
  RegisterComponents('Component', [TDBGridEx]);
end;

end.

---------------------------------------------------------

使用方法は

//1行ごとに背景色を変える
procedure TForm3.DBGridEx1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
    if DBGridEx1.SaveRow mod 2 = 0 then
    begin
      DBGridEx1.Canvas.Brush.Color := clRed;
    end
    else
    begin
      DBGridEx1.Canvas.Brush.Color := clBlue;
    end;
    DBGridEx1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
end;

//編集中の背景の色も変える
procedure TForm3.DBGridEx1MouseDown2(Sender: TObject; Row, Col: Integer);
begin
    if Row mod 2 = 0 then
    begin
      DBGridEx1.InplaceEditor.Brush.Color := clRed;
    end
    else
    begin
      DBGridEx1.InplaceEditor.Brush.Color := clBlue;
    end;
end;

BDS2006 + XP


マッキー  2007-11-30 22:29:33  No: 28696

KHE00221さん、またまたありがとうございました。
マウスクリックも上記ソースだと問題なかったです。。が。。
色合いを変えようと思って、
   begin
      DBGridEx1.Canvas.Brush.Color := clwhite;
//      DBGridEx1.Canvas.Brush.Color := clRed;
    end
    else
    begin
      DBGridEx1.Canvas.Brush.Color := clGradientInactiveCaption;
//     DBGridEx1.Canvas.Brush.Color := clBlue;

に変更したところ、背景色が白の部分が
マウスクリックすると、真っ白になります。
MouseDown2の色の部分を色々と変更しても改善されません。
何故なのでしょうか??


KHE00221  2007-12-01 04:20:03  No: 28697

フォントの色も設定して下さい。

    if DBGridEx1.SaveRow mod 2 = 0 then
    begin
      DBGridEx1.Canvas.Font.Color  := clBlack;
      DBGridEx1.Canvas.Brush.Color := clWhite;
    end
    else
    begin
      DBGridEx1.Canvas.Font.Color  := clWhite;
      DBGridEx1.Canvas.Brush.Color := clBlack;
    end;

また

DBGridEx.pas  に

  TInplaceEdit2 = class(TInplaceEdit)
  private
  published
    property Font;
  end;

を追加して

    if Row mod 2 = 0 then
    begin
      TInplaceEdit2(DBGridEx1.InplaceEditor).Font.Color := clBlack;
      DBGridEx1.InplaceEditor.Brush.Color := clWhite;
    end
    else
    begin
      TInplaceEdit2(DBGridEx1.InplaceEditor).Font.Color := clWhite;
      DBGridEx1.InplaceEditor.Brush.Color := clBlack;
    end;

としてみて下さい


マッキー  2007-12-05 17:51:12  No: 28698

KHE00221 さん  ご連絡遅れて申し訳ございません。
TInplaceEdit2の部分で未定義の識別子としてコンパイルエラーがでます。
DBGridEx.pas  に    TInplaceEdit2 = class(TInplaceEdit)...は追加して
念のため、コンポーネントから削除、追加しました。
DBGridEx.pas  は現在下記のようになっていますが、追加の方法が
悪いのでしょうか???

unit DBGridEx;
interface
uses
  Windows,SysUtils, Classes, Messages, Graphics, Controls, Grids, DBGrids;
type
 ///  2007/12/05 追加
 TInplaceEdit2 = class(TInplaceEdit)
  private
  published
    property Font;
  end;
 /// //////

  TMouseDown2Event = procedure(Sender:TObject;Row,Col:Integer) of Object;

  TDBGridEx = class(TDBGrid)
  private
    FSaveRow : Integer;
    FSaveCol : Integer;
    FMouseDown2Event : TMouseDown2Event;
  public
以下省略。。。

たびたびですみません、よろしくお願いいたします。


KHE0221  2007-12-05 18:18:36  No: 28699

DBGridExソースです

unit DBGridEx;

interface

uses
  Windows, Classes, Messages, Grids, DBGrids;

type

  TMouseDown2Event = procedure(Sender:TObject;Row,Col:Integer) of Object;

  TInplaceEdit2 = class(TInplaceEdit)
  private
  published
    property Font;
  end;

  TDBGridEx = class(TDBGrid)
  private
    FSaveRow : Integer;
    FSaveCol : Integer;
    FMouseDown2Event : TMouseDown2Event;
  public
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
  published
    property SaveRow : Integer read FSaveRow;
    property SaveCol : Integer read FSaveCol;
    property InplaceEditor;
    property Row;
    property Col;
    property OnMouseDown2 : TMouseDown2Event read FMouseDown2Event write FMouseDown2Event;
  end;

procedure Register;

implementation

procedure TDBGridEx.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
begin
    FSaveRow := ARow;
    FSaveCol := ACol;
    inherited;
end;

procedure TDBGridEx.WMLButtonDown(var Message: TWMLButtonDown);
begin
    inherited;
    if Assigned(InplaceEditor) = True then
    begin
      if Assigned(FMouseDown2Event) = True then OnMouseDown2(Self,Row,Col);
    end;
    Exit;
end;

procedure Register;
begin
  RegisterComponents('KHE00221 - DB', [TDBGridEx]);
end;

end.


ofZ  2007-12-05 20:57:34  No: 28700

どうせキャストするなら・・・

type
  //TInplaceEdit2 = class(TInplaceEdit)
  TInplaceEdit2 = class(TDBGridInplaceEdit)
    (略)
  end;

type
  TDBGridEx = class(TDBGrid)
  protected
    function  CreateEditor: TInplaceEdit; override;
  end;

function TDBGridEx.CreateEditor: TInplaceEdit;
begin
  Result := TInplaceEdit2.Create(Self);
end;

・・・のほうが・・・


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加