在DBGrid中使用Canvas.TextOut - Delphi XE 3

时间:2017-05-24 02:11:30

标签: delphi vcl delphi-xe3

请,我需要帮助使用Canvas: 当用户将鼠标移动到DBGrid的标题列上时, 标题描述在Delphi XE 3中消失了。 在delphI 7中不会出现此问题。

请遵循以下代码:

unit Unit1;

interface

uses

Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Graphics, Controls, Forms, Dialogs, Data.DB, Datasnap.DBClient,
Grids, DBGrids, Types, StdCtrls;

type
TAccessDBGrid = class(TCustomGrid);

type
TForm1 = class(TForm)

DataSource1: TDataSource;
grid1: TDBGrid;
cdsTabela: TClientDataSet;
cdsTabelacodigo_1: TIntegerField;
cdsTabelacodigo_2: TIntegerField;`enter code here`

procedure grid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);

procedure FormCreate(Sender: TObject);

procedure FormResize(Sender: TObject);

procedure grid1TitleClick(Column: TColumn);

private
    { Private declarations }
public
    { Public declarations }
end;

var
Form1: TForm1;

implementation
    {$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
    begin
        cdsTabela.CreateDataSet;
    end;

procedure TForm1.FormResize(Sender: TObject);
    begin
        grid1.Refresh;
    end;

procedure TForm1.grid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
S1 : string;

begin

with TAccessDBGrid(grid1) do
begin
    RowHeights[0] := 29;
    Canvas.Brush.Color := clBtnFace;
    case Column.Index of
    0:
    begin
        Column.Title.Caption := '';
        S1 := 'Code';
    end;
    1:
    begin
        Column.Title.Caption := '';
        S1 := 'Description';
    end;
end;

TDBGrid(Sender).Canvas.Font.Color:= clBlack;
Canvas.TextOut(Rect.Left + 3, 19, S1);
end;
end;

procedure TForm1.grid1TitleClick(Column: TColumn);
begin
ShowMessage('Title Click! ');
end;

end

有关详细信息,请参阅我发布的答案。

2 个答案:

答案 0 :(得分:2)

您发布的答案中包含的额外信息使您更容易理解您要做的事情,这很好。请在未来的问题中尝试这样做,因为您更有可能更快地得到更好的答案。

无论如何,我建议你用Mike Shkolnik的TSMDBGrid替换你的TDBGrid。请参阅:http://www.scalabium.com/smdbgrid.htm并观看动画。

他的网格包含一个OnDrawColumnTitle事件,我认为这比使用TDBGrid更容易实现你想要的事情。我从你的评论中得知你已经遵循了这个建议并成功完成了你想要做的事情。

原始答案如下:

我同意Ken White所说的话,但另外,我认为你的代码 是误解。要明白我的意思,试试这个:

  1. 保存代码编辑器不重叠的IDE调试布局 你的Form1。这样做的目的是使Form1不被强制重绘 IDE在断点上存放。

  2. DefaultDrawing设为False。关键在于将其设置为 真实地隐藏了Grid1DrawColumnCell的破坏程度。

  3. Grid1DrawColumnCell的第一行放置一个断点,即 with TAccessDBGrid(grid1)

  4. 编译并运行。请注意,调试器在断点上停止了几次 表格在屏幕上绘制时的次数,但之后却没有 完全停止你的血压。因此,一旦表单出现在屏幕上,您的自定义绘画就不会出现,直到您使网格刷新为止。使用表单的OnResize处理程序。

  5. 因此,一旦移动鼠标,导致列标题字幕为空白的原因 在网格上。答案是,你这样做!要明白为什么......

  6. 在VCL.DBGrids.Pas中,在TCustomDBGrid.DrawCell中找到DrawTitleCell并输入BP WriteText(Canvas,TextRect,LFrameOffs,LFrameOffs,Caption,Alignment,...

  7. 再次运行应用程序到Grid1DrawColumnCell已执行的位置 并且调试器在步骤6中设置的WriteText BP上停止。评估Caption 你会看到它是空的(因为你的Grid1DrawColumnCell已经清除了它)。我想你可以在DrawColumnCell退出之前将你的S1值分配给列标题的标题,但是绘制它 会不会是一团糟,正如你会看到的那样,例如。

    case Column.Index of
    0: begin
    //   Column.Title.Caption := '';
         S1 := 'Code';
         Column.Title.Caption := S1;
    end;
    1: begin
    //   Column.Title.Caption := '';
         S1 := 'Description';
         Column.Title.Caption := S1;
    end;
    
  8. QED

    所以基本上你是在浪费你的Grid1DrawColumnCell时间。如果你 想知道是否可以自定义列标题/标题,如果是,如何, 在做了一些研究之后,我建议你问一个新的q。如果您没有找到任何内容,可以考虑派生TCustomDBGrid后代并覆盖其DrawCell;这样你就可以更好地控制整个绘图过程,也可以更接近你想要实现的目标。

    以上是基于在Delphi Seatlle中编译的应用程序,它比XE3更新,但我怀疑这有什么不同。

答案 1 :(得分:1)

我使用Canvas.TextOut而不是Title.Caption的原因是   我需要在Title中写两行:

        Tests
Test One    Test Two

我用" 19"而不是Rect.Top,因为我想写在标题。   如果我使用Rect.Top,则在列

的编辑区域中绘制文本

Canvas.TextOut(Rect.Left + 3,19,S1);

跟随我的真实代码:

在Grid1DrawColumnCell中:

with TAccessDBGrid(grid1) do
begin
  RowHeights[0] := 37;
  Canvas.Brush.Color := clBtnFace;

  case Column.Index of
  0: begin
       Column.Title.Caption := '';
       S1 := 'Code';
     end;
  1: begin
       Column.Title.Caption := '';
       Canvas.Font.Color := clBlack;

       S1 := 'Tests';

       Canvas.Brush.Style := bsSolid;
       Canvas.Brush.Color := clBtnFace;
       Canvas.FillRect(Types.Rect(Rect.Left, 0, Rect.Left + 120, 18));
       Canvas.TextOut(Rect.Left + 3, 1, S1);
       Canvas.Brush.Style := bsSolid;

       S1 := 'Test One';
     end;
  2: begin
       Column.Title.Caption := '';
       S1 := 'Test Two';
     end;
 end;

  Canvas.Font.Color:= clBlack;
  Canvas.TextOut(Rect.Left + 3, 19, S1);
end;