cxGrid显示行号的两种方式和两种代码

第一种方式:直接双击events中的对应OnCustomDrawIndicatorCell事件,使用此代码

//==============================================================================

// 显示cxGrid的行号
//==============================================================================

procedure TFormMainOperation.cxgrddbbandtv1CustomDrawIndicatorCell(
  Sender: TcxGridTableView; ACanvas: TcxCanvas;
  AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);
var
  AIndicatorViewInfo: TcxGridIndicatorRowItemViewInfo;
  ATextRect: TRect;
 // AStyle: TcxStyle;
  aCV: TcxCanvas;
begin
  if not (AViewInfo is TcxGridIndicatorRowItemViewInfo) then
    Exit;
  aCV := ACanvas;
  ATextRect := AViewInfo.ContentBounds;
  AIndicatorViewInfo := AViewInfo as TcxGridIndicatorRowItemViewInfo;
  InflateRect(ATextRect, -2, -1);
  if AIndicatorViewInfo.GridRecord.Selected then //这个if段是为了在行号处把把选中的行号跟别的区分开,可不用
    begin
      aCV.Font.Style := Canvas.Font.Style + [fsBold];
      aCV.Font.Name := '黑体';
      aCV.Font.Size := 12;
      aCV.Font.Color := clRed;
    end
  else
    begin
      aCV.Font.Style := Canvas.Font.Style - [fsBold];
      acv.Font.Color := Canvas.Font.Color;
    end;
  Sender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.ContentBounds,
    ATextRect, [], cxBordersAll, cxbsNormal, taCenter, vaCenter,
    False, False, IntToStr(AIndicatorViewInfo.GridRecord.Index + 1),
//    AStyle.Font, AStyle.TextColor, AStyle.Color);
    acv.Font, acv.font.Color, acv.Brush.color);
  ADone := True;

end;


第二种方式:使用封装类,建立储存过程,Form初始化OnCreate事件中调用

1、建立封装类和调用函数

unit UnitDevExpressVCLCustom;

interface


uses
  cxGridTableView, cxGridDBBandedTableView, Winapi.Windows, System.SysUtils, cxClasses,
  System.Classes, Vcl.Graphics, cxGraphics, cxLookAndFeels, cxLookAndFeelPainters;


type
  TMyCxGrid = class(TObject)


    class procedure DrawIndicatorCell(Sender: TcxGridTableView; ACanvas: TcxCanvas;
      AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);


  end;


  procedure ShowLineNo(cxGridDBBandedTableView: TcxGridDBBandedTableView);


implementation


{-------------------------------------------------------------------------------
  作者:      曾聪
  日期:      2013.10.07
  过程名:    TMyCxGrid.DrawIndicatorCell
  功能:      显示cxGrid的行号
  参数:      Sender: TcxGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean
  返回值:    无
  说明:
-------------------------------------------------------------------------------}


class procedure TMyCxGrid.DrawIndicatorCell(Sender: TcxGridTableView; ACanvas: TcxCanvas;
  AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);
var
  FValue: string;
  FBounds: TRect;
  //method 2
  AIndicatorViewInfo: TcxGridIndicatorRowItemViewInfo;
  ATextRect: TRect;
  AFont: TFont;
  AFontTextColor, AColor: TColor;
begin
  AFont := ACanvas.Font;
  AColor := clBtnFace;
  AFontTextColor := clWindowText;
  if (AViewInfo is TcxGridIndicatorHeaderItemViewInfo) then //设置显示行号那一列的标题名称为“序号”
    begin
      ATextRect := AViewInfo.Bounds;
      InflateRect(ATextRect, -1, -1);
      Sender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.Bounds,
        ATextRect, [], cxBordersAll, cxbsNormal, taCenter, TcxAlignmentVert.vaCenter,
        False, False, '序号', AFont, AFontTextColor, AColor);
      ADone := True;
    end;
  if not (AViewInfo is TcxGridIndicatorRowItemViewInfo) then
    Exit;
  ATextRect := AViewInfo.ContentBounds;
  AIndicatorViewInfo := AViewInfo as TcxGridIndicatorRowItemViewInfo;
  InflateRect(ATextRect, -1, -1);
  if AIndicatorViewInfo.GridRecord.Selected then //这个if段是为了在行号处把把选中的行号跟别的区分开,可不用
    begin
      AFont.Style := ACanvas.Font.Style + [fsBold];
      AFont.Name := '黑体';
      AFont.Size := 12;
      AFont.Color := clRed;
    end
  else
    begin
      AFont.Style := ACanvas.Font.Style - [fsBold];
    end;
  Sender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.ContentBounds,
    ATextRect, [], [bBottom, bLeft, bRight], cxbsNormal, taCenter, TcxAlignmentVert.vaCenter,
    False, False, IntToStr(AIndicatorViewInfo.GridRecord.Index + 1),
    AFont, AFontTextColor, AColor);
  ADone := True;


end;

{-------------------------------------------------------------------------------
  作者:      曾聪
  日期:      2013.10.07
  过程名:    ShowLineNo
  功能:      设置cxGrid显示导航列、导航列宽、调用显示行号函数
  参数:      cxGridDBBandedTableView: TcxGridDBBandedTableView
  返回值:    无
  说明:
-------------------------------------------------------------------------------}
procedure ShowLineNo(cxGridDBBandedTableView: TcxGridDBBandedTableView);
begin
  cxGridDBBandedTableView.OptionsView.Indicator := True;
  cxGridDBBandedTableView.OptionsView.IndicatorWidth := 30;
  cxGridDBBandedTableView.OnCustomDrawIndicatorCell := TMyCxGrid.DrawIndicatorCell;
end;

end.


2、在Form的OnCreate事件中调用:

procedure TFormMainOperation.FormCreate(Sender: TObject);
begin
  ShowLineNo(cxgrddbbandtv1);
end;




以上代码如果需要在右侧仍然显示指针效果:

1、在最后一行end之前增加一行代码:

Sender.LookAndFeelPainter.DrawIndicatorImage(ACanvas, ATextRect, AIndicatorViewInfo.IndicatorKind);

2、DrawIndicatorImage 从这里跟进去(Ctrl+左键单击) 
在 cxLookAndFeelPainters 单元中作如下修改: 
class procedure TcxCustomLookAndFeelPainter.DrawIndicatorImage(ACanvas: TcxCanvas; 
   const R: TRect; AKind: TcxIndicatorKind); 
var 
   X, Y: Integer; 
begin 
   if AKind = ikNone then Exit; 
   with cxIndicatorImages, R do 
   begin 
     X := (Left + Right - Width);               //靠右,在各函数只修改这一个地方 
     Y := (Top + Bottom - Height) div 2;       //居中 
   end; 
   cxIndicatorImages.Draw(ACanvas.Canvas, X, Y, Ord(AKind) - 1); 
end; 
注意,我已注明靠右的那一行, 就是去掉 DIV 2 了, 此为1226版本的修改,13.1.2修改类似也是去掉DIV 2,但是左右宽的代码使用的是变量R.Left等
3、还要改一个地方: 
SKIN控件目录下的dxSkinLookAndFeelPainter单元,找到 
TdxSkinLookAndFeelPainter.DrawIndicatorImage 函数 
的 
OffsetRect(ARect, (Left + Right - cx div 2) , (Top + Bottom - cy) div 2); 
这一行,将 (Left + Right - cx div 2) 改为(Left + Right - cx) 也是去掉 div 2 就是靠右; 
修改后: OffsetRect(ARect, (Left + Right - cx) , (Top + Bottom - cy) div 2); 
使用 
procedure TForm1.cxGrid1DBTableView1CustomDrawIndicatorCell( 
   Sender: TcxGridTableView; ACanvas: TcxCanvas; 
   AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean); 
begin 
     SetRowNumber(Sender,AviewInfo,ACanvas,ADone); 
end; 
序号列的列宽最好改为40左右,因为数据记录过多会出现重叠现象(数字和指针图标在一起了)!




<think> 首先,用户的问题是:“我想查找CXGRID显示行号的方法 请问CXGRID如何显示行号”。这与之前的引用相关,引用中提到了cxGrid显示行号的方法。 从引用中,我总结出关键点: - 引用[1]:在OnCustomDrawIndicatorCell事件中设置代码,使用SetRowNumber函数。 - 引用[2]:定义一个类TMyCxGrid,其中包含DrawIndicatorCell过程。 - 引用[3]:在绘制指示器单元格时,处理选中行的样式(如加粗、颜色)。 - 引用[4]:启用指示器选项并设置事件处理程序,如设置tvList.OptionsView.Indicator和tvList.OnCustomDrawIndicatorCell。 用户的需求是了解如何在cxGrid显示行号cxGrid是DevExpress的一个组件,用于Delphi开发。 系统指令要求我: - 所有行内数学表达式用$...$。 - 独立公式用$$...$$并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 用户的问题是关于编程的,没有数学表达式,所以LaTeX部分可能不适用,但如果有公式,我会处理。 步骤1:理解问题并参考引用。 用户需要知道cxGrid如何显示行号。引用提供了方法:通过自定义绘制指示器单元格来显示行号。 关键步骤: 1. 启用指示器:设置OptionsView.Indicator为True,并设置IndicatorWidth。 2. 定义事件处理程序:为OnCustomDrawIndicatorCell事件编写代码。 3. 在事件中绘制行号:通常通过访问网格的行索引来显示行号。 从引用[1]和[2],有SetRowNumber函数或DrawIndicatorCell过程。 引用[1]提到了SetRowNumber函数,但没有给出实现。引用[2]给出了DrawIndicatorCell过程的类定义。引用[3]提供了绘制的细节,如字体样式。引用[4]展示了如何设置事件。 我应该提供一个完整的示例代码,因为用户需要知道如何实现。 生成相关问题: 指令要求“生成相关问题”,所以我需要在回答末尾添加相关问题。 回答结构: - 结构清晰,逐步解决问题。 - 解释每个步骤。 可能的结构: 1. 介绍cxGrid显示行号的基本方法。 2. 详细步骤:启用指示器、设置事件、编写事件处理程序。 3. 提供代码示例。 4. 引用引用的信息。 确保使用中文。 最终回答: - 开头:直接回答用户问题。 - 主体:步骤解释和代码。 - 结尾:相关问题。 相关问题示例: 1. 如何自定义cxGrid行号的颜色或样式? 2. cxGrid行号显示不正确怎么办? 3. 如何实现动态更新的行号? 现在,编译信息。 从引用中: - 启用指示器:tvList.OptionsView.Indicator := True; tvList.OptionsView.IndicatorWidth := 30; [^4] - 设置事件:tvList.OnCustomDrawIndicatorCell := TMyCxGrid.DrawIndicatorCell; [^4] - 事件处理程序:在DrawIndicatorCell中绘制行号。引用[3]有样式代码。 完整代码示例: 定义一个类或事件处理程序。 例如: ```pascal procedure TForm1.cxGrid1DBTableView1CustomDrawIndicatorCell(Sender: TcxGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean); var RowNumber: Integer; begin // 获取行号 RowNumber := AViewInfo.GridRecord.Index + 1; // 索引从0开始,所以+1显示从1开始的行号 // 绘制行号 ACanvas.TextOut(AViewInfo.Bounds.Left, AViewInfo.Bounds.Top, IntToStr(RowNumber)); ADone := True; // 表示已处理绘制 end; ``` 在窗体创建时设置选项: ```pascal cxGrid1DBTableView1.OptionsView.Indicator := True; cxGrid1DBTableView1.IndicatorWidth := 30; // 设置宽度 ``` 引用中提到SetRowNumber函数,但未给出,所以我提供一个简单版本。 在引用[1]中,调用了SetRowNumber,但没有代码,所以我应该基于引用合成。 为了完整,我可以创建一个类似SetRowNumber的函数。 但保持简单。 响应结构: 1. 启用指示器。 2. 定义OnCustomDrawIndicatorCell事件处理程序。 3. 在事件中绘制行号。 添加样式如引用[3]。 在回答中,自然地添加引用标识。 例如,当提到某个点时,添加[^1]。 现在,生成相关问题。 相关问题: 1. 如何更改cxGrid行号的字体或颜色? 2. cxGrid行号不更新时如何处理? 3. 如何在cxGrid显示所有行的行号,包括分组行? 确保回答真实可靠。 </think>### cxGrid 显示行号的方法 cxGrid 是 Delphi 开发中常用的 DevExpress 组件库的一部分。要显示行号,需要通过自定义绘制指示器单元格(Indicator Cell)来实现。以下是详细步骤和完整示例代码,确保您能逐步实现该功能。 #### 步骤 1: 启用指示器选项 首先,在您的窗体或数据模块中,设置 cxGrid 的视图属性以启用指示器列: - 设置 `OptionsView.Indicator` 为 `True`,这会显示指示器列。 - 设置 `IndicatorWidth` 来定义列宽(例如 30 像素)。 示例代码: ```pascal // 在窗体创建时设置选项 procedure TForm1.FormCreate(Sender: TObject); begin cxGrid1DBTableView1.OptionsView.Indicator := True; // 启用指示器 cxGrid1DBTableView1.IndicatorWidth := 30; // 设置列宽 end; ``` 此步骤确保指示器列可见,为后续绘制行号做准备[^4]。 #### 步骤 2: 定义自定义绘制事件处理程序 cxGrid 的 `OnCustomDrawIndicatorCell` 事件用于在指示器单元格中绘制自定义内容(如行号)。您需要为该事件添加处理程序: - 在事件中获取当前行索引,并将其转换为行号(索引从 0 开始,行号通常从 1 开始)。 - 可选:添加样式(如选中行高亮),以提升用户体验。 示例代码(完整事件处理程序): ```pascal // 在 cxGrid1DBTableView1 的 OnCustomDrawIndicatorCell 事件中添加以下代码 procedure TForm1.cxGrid1DBTableView1CustomDrawIndicatorCell( Sender: TcxGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean); var RowNumber: Integer; begin // 获取行号(索引+1) if AViewInfo.GridRecord <> nil then begin RowNumber := AViewInfo.GridRecord.Index + 1; // 索引从0开始,+1后显示为1,2,3... // 可选:为选中行添加样式(如加粗和红色) if AViewInfo.GridRecord.Selected then begin ACanvas.Font.Style := ACanvas.Font.Style + [fsBold]; // 加粗 ACanvas.Font.Color := clRed; // 红色字体 end else begin ACanvas.Font.Style := ACanvas.Font.Style - [fsBold]; // 取消加粗 ACanvas.Font.Color := clBlack; // 默认黑色 end; // 绘制行号文本 ACanvas.TextOut( AViewInfo.Bounds.Left + 5, // 水平偏移,避免贴边 AViewInfo.Bounds.Top + 2, // 垂直偏移 IntToStr(RowNumber) // 行号文本 ); end; ADone := True; // 标记绘制已完成,阻止默认绘制 end; ``` 此代码会为每行显示行号,并自动处理选中行的样式(如引用[3]所述)[^3]。 #### 步骤 3: 连接事件处理程序 在窗体设计时或代码中,将事件处理程序与 cxGrid 视图关联: - 在 Delphi IDE 的对象检查器中,设置 `OnCustomDrawIndicatorCell` 事件为上述过程。 - 或直接在代码中赋值: ```pascal // 在窗体的 OnCreate 事件中连接 procedure TForm1.FormCreate(Sender: TObject); begin cxGrid1DBTableView1.OptionsView.Indicator := True; cxGrid1DBTableView1.IndicatorWidth := 30; cxGrid1DBTableView1.OnCustomDrawIndicatorCell := cxGrid1DBTableView1CustomDrawIndicatorCell; // 连接事件 end; ``` #### 完整示例 将上述步骤整合到一个简单窗体中: 1. 创建一个新 Delphi 窗体,添加 cxGridcxGridDBTableView 和数据源(如 ADOQuery)。 2. 在窗体单元文件中实现代码: ```pascal unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, cxGraphics, cxControls, cxLookAndFeels, cxLookAndFeelPainters, cxStyles, cxCustomData, cxFilter, cxData, cxDataStorage, cxEdit, cxNavigator, Data.DB, cxDBData, cxGridLevel, cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGridCustomView, cxGrid; type TForm1 = class(TForm) cxGrid1: TcxGrid; cxGrid1DBTableView1: TcxGridDBTableView; cxGrid1Level1: TcxGridLevel; procedure cxGrid1DBTableView1CustomDrawIndicatorCell( Sender: TcxGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin // 启用指示器并设置宽度 cxGrid1DBTableView1.OptionsView.Indicator := True; cxGrid1DBTableView1.IndicatorWidth := 30; end; procedure TForm1.cxGrid1DBTableView1CustomDrawIndicatorCell( Sender: TcxGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean); var RowNumber: Integer; begin if AViewInfo.GridRecord <> nil then begin RowNumber := AViewInfo.GridRecord.Index + 1; // 样式处理:选中行高亮 if AViewInfo.GridRecord.Selected then begin ACanvas.Font.Style := ACanvas.Font.Style + [fsBold]; ACanvas.Font.Color := clRed; end else begin ACanvas.Font.Style := ACanvas.Font.Style - [fsBold]; ACanvas.Font.Color := clBlack; end; ACanvas.TextOut(AViewInfo.Bounds.Left + 5, AViewInfo.Bounds.Top + 2, IntToStr(RowNumber)); end; ADone := True; end; end. ``` #### 注意事项 - **性能优化**:如果数据量大,确保绘制代码高效,避免频繁计算(如直接使用索引)。 - **兼容性**:此方法适用于 cxGridDBTableView 或 cxGridTableView。如果使用分组,需额外处理分组行(通常忽略或显示为空白)。 - **引用说明**:上述方法基于 DevExpress 组件的标准事件处理,如引用[1][2][3][4]所述,通过自定义绘制实现行号显示[^1][^2][^3][^4]。 如果您遇到问题(如行号不更新),检查数据源是否刷新,或添加事件(如 `OnDataChanged`)强制重绘。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值