在DBGrid-delphixe3中使用Canvas.TextOut

在DBGrid-delphixe3中使用Canvas.TextOut,delphi,vcl,delphi-xe3,Delphi,Vcl,Delphi Xe3,请,我需要帮助您使用画布: 当用户将鼠标移动到DBGrid的标题列上时, 标题描述在Delphi XE 3中消失。 这个问题在Delphi7中没有出现 请遵循以下代码: unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Graphics, Controls, Forms, Dialogs, Data.DB, Datasna

请,我需要帮助您使用画布: 当用户将鼠标移动到DBGrid的标题列上时, 标题描述在Delphi XE 3中消失。 这个问题在Delphi7中没有出现

请遵循以下代码:

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

有关更多信息,请参阅我发布的答案。

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

无论如何,我建议你用Mike Shkolnik的TSMDBGrid替换你的TDBGrid。请参见:并观看动画

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

原答覆如下:

我同意Ken White所说的,但除此之外,我认为您的代码 这是一种误解。要了解我的意思,请尝试以下方法:

  • 保存一个IDE调试布局,其中代码编辑器与 你的表格1。这样做的目的是使Form1不会被迫重新绘制 IDE在断点上STO的

  • DefaultDrawing
    设置为False。关键是把它设置为 True隐藏了
    Grid1DrawColumnCell
    的破坏程度

  • Grid1DrawColumnCell
    的第一行上放置断点,即。
    使用TAccessDBGrid(grid1)

  • 编译并运行。请注意,调试器在断点处停止了几次 当窗体被绘制在屏幕上时,会出现多次,但之后不会出现 停止你的血压。因此,一旦表单出现在屏幕上,您的自定义绘制就不会发生,除非您使用表单的
    OnResize
    处理程序刷新网格

  • 那么,移动鼠标后,是什么导致列标题为空 在网格上。答案是,你知道!看看为什么

  • 在VCL.DBGrids.Pas中,在TCustomDBGrid.DrawCell中找到DrawTitleCell并在其上放置BP WriteText(画布、TextRect、LFrameoff、LFrameoff、标题、对齐等)

  • 再次运行应用程序,直到执行了
    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;
    
  • 量化宽松

    因此,基本上你是在浪费时间在
    Grid1DrawColumnCell
    上 想知道是否可以自定义绘制列标题/标题,如果可以,如何自定义, 我建议你在做了一些研究之后再问一个新的Q。如果你找不到任何东西,你可以考虑导出一个TutuxDbGrand子孙并覆盖它的<代码> DRACECEL 。这样,你可以更好地控制整个绘图过程,并且可能更接近你正在尝试的任何东西。
    顺便说一句,上面是基于在Delphi Seatlle中编译的应用程序,它比XE3更新,但我怀疑这有什么区别。

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

            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;
    

    在您已经开始绘制行之后,您希望如何更改行高度才能正常工作?我没有这台机器上的D7,但我认为它在那里也不起作用。请改为在FormCreate事件中设置行高度。为什么您在调用
    Canvas.TextOut
    而不是usin时硬编码
    19
    g与
    Rect.Top
    的偏移量?如果您更改为使用
    19
    ,而不是使用
    19
    ,会发生什么情况?您的代码没有任何意义;您删除了每一行的标题、标题,并在每一行的每个单元格中从S1绘制相同的文本。此代码从未工作过。@KenWhite:您说“此代码从未工作过”是正确的。它在我的D7中肯定不能正常工作。我添加了一个答案来解释我的问题。谢谢Martyn,您使用TSMDBGrid而不是TDBGrid的建议解决了我的问题,而且它做得更多!我为两个专栏创建了一个乐队,现在可以工作了!祝贺您!如果您一开始就发布了真正的代码,它会有所帮助的!对不起,我我想我会简化代码让你明白。但是我不能。拜托,你能帮我吗?