Delphi TListview自绘某列添加图片按钮并实现点击事件响应

最终实现的效果如下图

点击对应列对应行按钮。显示出对应行的caption字段的值 

 

完整源码如下

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ExtCtrls, ComCtrls, StdCtrls, Spin, Buttons, ImgList;

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    StatusBar1: TStatusBar;
    ListView1: TListView;
    Panel1: TPanel;
    Label1: TLabel;
    cbSource: TComboBox;
    cbDestination: TComboBox;
    Label2: TLabel;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    Label3: TLabel;
    DateTimePicker1: TDateTimePicker;
    btnQuery: TButton;
    CheckBox1: TCheckBox;
    SpinEdit1: TSpinEdit;
    Label4: TLabel;
    ImageList1: TImageList;
    Label5: TLabel;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    CheckBox6: TCheckBox;
    CheckBox7: TCheckBox;
    SpeedButton1: TSpeedButton;
    procedure ListView1CustomDrawSubItem(Sender: TCustomListView;
      Item: TListItem; SubItem: Integer; State: TCustomDrawState;
      var DefaultDraw: Boolean);
    procedure btnQueryClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure  Look(Sender: TObject);
    procedure Init;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  bmp:TBitmap;
implementation

{$R *.dfm}

procedure TForm1.btnQueryClick(Sender: TObject);
begin
  bmp:=TBitmap.Create;
  bmp.LoadFromFile('Snipaste_2022-12-12_02-15-59.bmp');
  Init;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.DoubleBuffered:=True;
end;

procedure TForm1.Init;
var
  Item: TListItem;
  i: Integer;
begin
  ListView1.Items.Clear;
  for i := 1 to 15 do
  begin
    Randomize; //初始化随机数发生器
    Item := ListView1.Items.Add;
    Item.Caption := 'G'+ IntToStr(Random(10000));
    Item.SubItems.Add(IntToStr(10 + i));
    Item.SubItems.Add(IntToStr(100 + i));
    Item.SubItems.Add(IntToStr(1000 + i));
    Item.SubItems.Add(IntToStr(2000 + i));
    Item.SubItems.Add(IntToStr(3000 + i));
    Item.SubItems.Add(IntToStr(4000 + i));
    Item.SubItems.Add(IntToStr(5000 + i));
    Item.SubItems.Add('有');
    Item.SubItems.Add('-');
    if i mod 2 = 1 then  Item.SubItems.Add('有')
    else  Item.SubItems.Add(IntToStr(Random(20)));

    Item.SubItems.Add(IntToStr(9000 + i));
    Item.SubItems.Add('-');
    Item.SubItems.Add(IntToStr(1100 + i));
    Item.SubItems.Add(IntToStr(1200 + i));
    Item.SubItems.Add(IntToStr(1300 + i));
    Item.SubItems.Add(IntToStr(1400 + i));
    //Item.SubItems.Add(IntToStr(2500 + i));
    Item.SubItems.Add('');
  end;

end;






//---------------------------------------------------------------------------
{
var
  I, J: Integer;
  P: TSpeedButton;

for I := 0 to FlstVisbleB.Count -1 do
begin
  P := TSpeedButton(FlstVisbleB.Objects[I]);
  P.Visible := False;
  if P.Tag <> 0 then
  begin
    TImage(P.Tag).Visible := False;
    TImage(P.Tag).Left := J;
  end;
end;
}
procedure  TForm1.Look(Sender: TObject);
var
  pb:TSpeedButton;
  p:TListItem;

begin
  //ShowMessage('您点击了');
   pb := TSpeedButton(Sender);
   p := TListItem(pb.Tag);
   //pb.Visible := false;
   //ShowMessage(Format('pb.Tag:%d | Caption:%s',[pb.Tag , ListView1.Items[pb.Tag].Caption]));
   //if(p.SubItems.Count >0) then
   //ShowMessage(p.SubItems.Strings[10]);
   ShowMessage(p.Caption);

end;


procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  Rect: TRect;
  Button: TSpeedButton;
begin
  //DefaultDraw := False; // 不显示默认的文本.
  { 比如:第2列上显示CheckBox,第5列上显示Button }
  //if SubItem in [2, 5] then
  if SubItem = 16 then
  begin
    if Item.Data = nil then
    begin
      DefaultDraw := False;
      Rect := Item.DisplayRect(drBounds); // 获取Item显示的区域.
      Button := TSpeedButton.Create(ListView1);

      Button.Parent := ListView1;
      //Button.Caption := '预定';
      Button.Glyph := bmp;
      Button.Width := 55;
      Button.Height := 22;
      Button.Left := Rect.Right - ((ListView1.Columns.Items[16].Width + Button.Width) div 2) - 7;

      Button.Top := Rect.Top;
      Button.Visible := True;
      Button.Flat := True;
      //Button.Tag := Item.Index; //ListView1中第几行  用这个也是ok的
      Button.Tag := Integer(Item);
      Item.Data := Button;

      Button.OnClick := Look;
    end;
  end;
end;

end.

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi 2010 的 TListView 组件本身不支持虚拟加载和分组,但可以通过继承 TListView 实现这些功能。以下是实现虚拟加载和分组的示例代码: ``` unit VirtualListView; interface uses ComCtrls; type TVirtualListViewItem = class(TListItem) private FLoaded: Boolean; public property Loaded: Boolean read FLoaded write FLoaded; end; TVirtualListViewGroup = class(TListGroup) private FLoaded: Boolean; public property Loaded: Boolean read FLoaded write FLoaded; end; TVirtualListView = class(TListView) private FVirtualItemCount: Integer; FVirtualItemHeight: Integer; FVirtualGroupCount: Integer; FVirtualGroupHeaderHeight: Integer; protected function CreateItem(AOwner: TListItem): TListItem; override; function CreateGroup(AOwner: TListGroup): TListGroup; override; procedure DoUpdateItems(FirstIndex, LastIndex: Integer); override; procedure DoUpdateGroups(FirstIndex, LastIndex: Integer); override; function GetItemCount: Integer; override; function GetItemHeight(AItem: TListItem): Integer; override; function GetGroupHeaderHeight: Integer; override; procedure SetVirtualItemCount(Value: Integer); procedure SetVirtualItemHeight(Value: Integer); procedure SetVirtualGroupCount(Value: Integer); procedure SetVirtualGroupHeaderHeight(Value: Integer); public constructor Create(AOwner: TComponent); override; property VirtualItemCount: Integer read FVirtualItemCount write SetVirtualItemCount; property VirtualItemHeight: Integer read FVirtualItemHeight write SetVirtualItemHeight; property VirtualGroupCount: Integer read FVirtualGroupCount write SetVirtualGroupCount; property VirtualGroupHeaderHeight: Integer read FVirtualGroupHeaderHeight write SetVirtualGroupHeaderHeight; end; implementation function TVirtualListView.CreateItem(AOwner: TListItem): TListItem; begin Result := TVirtualListViewItem.Create(Items); end; function TVirtualListView.CreateGroup(AOwner: TListGroup): TListGroup; begin Result := TVirtualListViewGroup.Create(Groups); end; procedure TVirtualListView.DoUpdateItems(FirstIndex, LastIndex: Integer); var I: Integer; begin for I := FirstIndex to LastIndex do begin if not Items[I].Loaded then begin Items[I].Loaded := True; // 加载项目数据 end; end; end; procedure TVirtualListView.DoUpdateGroups(FirstIndex, LastIndex: Integer); var I: Integer; begin for I := FirstIndex to LastIndex do begin if not Groups[I].Loaded then begin Groups[I].Loaded := True; // 加载分组数据 end; end; end; function TVirtualListView.GetItemCount: Integer; begin Result := FVirtualItemCount; end; function TVirtualListView.GetItemHeight(AItem: TListItem): Integer; begin Result := FVirtualItemHeight; end; function TVirtualListView.GetGroupHeaderHeight: Integer; begin Result := FVirtualGroupHeaderHeight; end; procedure TVirtualListView.SetVirtualItemCount(Value: Integer); begin FVirtualItemCount := Value; Items.Count := Value; end; procedure TVirtualListView.SetVirtualItemHeight(Value: Integer); begin FVirtualItemHeight := Value; end; procedure TVirtualListView.SetVirtualGroupCount(Value: Integer); begin FVirtualGroupCount := Value; Groups.Count := Value; end; procedure TVirtualListView.SetVirtualGroupHeaderHeight(Value: Integer); begin FVirtualGroupHeaderHeight := Value; end; constructor TVirtualListView.Create(AOwner: TComponent); begin inherited; OwnerData := True; end; end. ``` 在这个示例中,我们创建了两个新类:TVirtualListViewItem 和 TVirtualListViewGroup,它们分别继承自 TListItem 和 TListGroup,并增加了 Loaded 属性。这个属性用来标记项目或分组是否已经加载了数据。当项目或分组需要显示时,我们可以根据该属性来判断是否需要加载数据。 TVirtualListView 继承自 TListView,并重写了一些方法和属性。CreateItem 和 CreateGroup 方法分别创建 TVirtualListViewItem 和 TVirtualListViewGroup 对象。DoUpdateItems 和 DoUpdateGroups 方法分别在项目或分组需要显示时调用,用来加载数据。GetItemCount、GetItemHeight 和 GetGroupHeaderHeight 方法分别返回项目数、项目高度和分组标题高度。SetVirtualItemCount、SetVirtualItemHeight、SetVirtualGroupCount 和 SetVirtualGroupHeaderHeight 方法分别设置虚拟项目数、项目高度、虚拟分组数和分组标题高度。在 TVirtualListView 的构造函数中,我们将 OwnerData 属性设置为 True,这是启用虚拟模式的必要条件。 使用 TVirtualListView 时,可以像使用普通的 TListView 一样设置分组和项目,但需要设置虚拟属性。例如: ``` procedure TForm1.FormCreate(Sender: TObject); begin VirtualListView1.VirtualGroupCount := 100; VirtualListView1.Groups[0].Header := 'Group 1'; VirtualListView1.Groups[1].Header := 'Group 2'; VirtualListView1.VirtualItemCount := 1000; end; ``` 在上面的示例中,我们设置了虚拟分组数和虚拟项目数。我们还设置了前两个分组的标题。当需要显示分组或项目时,TVirtualListView 会自动调用 DoUpdateGroups 和 DoUpdateItems 方法,来加载数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值