Delphi在Listview中加入Eeit控件

转载 2013年12月04日 18:18:39

本文版权归原作者所有

来源:http://www.ctsys.cn/FILES/show_FILES.aspx?id=31 


       Listview是一个非常有用的控件,我们常常将大量的数据(如数据库里的数据)导入到Listview中,有的时候我们需要编辑Listview里的数据,而它并不提供编辑的功能,怎么样才能使它具有编辑功能呢?你可以试试下面这种方法。

         首先在FORM1中放置一个Listview控件和一个Eeit控件。Edit控件有什么用?当然是用来编辑Listview里的内容,程序的想法是这样的:当鼠标点击了Listview控件后,根据鼠标位置将Edit控件放置到Listview对应的Column里,将对应Item里的内容读入Edit中,在Edit中编辑好后,再将Edit编辑过的信息回写到Item中。

        代码如下:

unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, CommCtrl, StdCtrls, ImgList;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Edit1: TEdit;
    procedure Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Edit1Change(Sender: TObject);
    procedure ListView1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure ListView1ColumnDagged(Sender: TObject);
  private
    { Private declarations }

    FListViewWndProc1: TWndMethod;
    procedure ListViewWndProc1(var Msg: TMessage);
  public
    { Public declarations }
  end;

const MaxColumns=3 ;  //   总Columns-1
var
  Form1: TForm1;
  edtcol:integer; //记录EDIT1在Columns中的位置,1-  MaxColumns;
  editem:Tlistitem;
implementation

{$R *.dfm}

//拦截LISTVIEW1消息
procedure  TForm1.ListViewWndProc1(var Msg: TMessage);
var IsNeg : Boolean;
begin
 try
  ShowScrollBar(ListView1.Handle, SB_HORZ, false);

  //拖动Listview1滚动条时,将EDIT1隐藏起来
  if(msg.Msg  =WM_VSCROLL) or (msg.Msg=WM_MOUSEWHEEL ) then edit1.Visible :=false;
  if Msg.Msg = WM_MOUSEWHEEL then
   begin
    if listview1.Selected=nil then exit;
    IsNeg := Short(msg.WParamHi) < 0;
    listview1.SetFocus ;
    if IsNeg then
        SendMessage(edit1.Handle,  WM_KEYDOWN,  VK_down,  0)
    else
         SendMessage(edit1.Handle,  WM_KEYDOWN,  VK_up, 0);
  end
  else
   FListViewWndProc1(Msg);
 except
 end;
end;

//拦截EDIT的按键消息,对上、下、左、右方向键进行处理------
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var item:tlistitem;
    ix,lt,i:integer;
    rect:Trect;
begin
TRY
  //----对上、下、左、右方向键进行处理-----------------
  if(key<>VK_DOWN) AND (KEY<>VK_UP)  AND (KEY<>VK_RIGHT)  AND (KEY<>VK_LEFT)  THEN EXIT;
  IF(KEY=VK_RIGHT) THEN  //键盘右键
   BEGIN
     //按下键盘右键后,判断光标位置是否处于最右边,如果不在最右边,不作处理 EXIT
    if length(edit1.Text)>edit1.SelStart then exit;
     item:=listview1.Selected;
     //计算edit1位于哪个Columns,如果<最大Columns,+1,否则=1,即转到最左边

   if(edtcol

    //从 edtcol值计算出 Columns的位置(Left,width),EDIT1按此设置
     lt:=0;
     for i:=0 to edtcol-1 do lt:=lt+listview1.Columns[i].Width;
     edit1.Left:=lt+1;
     edit1.Width :=listview1.Columns[edtcol].Width;
  END;
    IF(KEY=VK_left) THEN  //键盘左键
   BEGIN
     if edit1.SelStart<>0 then exit;
     item:=listview1.Selected;
     if(edtcol>0) then  edtcol:=edtcol-1 else edtcol:=MaxColumns;
     lt:=0;
     for i:=0 to edtcol-1 do lt:=lt+listview1.Columns[i].Width;
     edit1.Left:=lt+1;
     edit1.Width :=listview1.Columns[edtcol].Width;
  END;
  if(key=VK_DOWN ) then     //键盘下键
   begin
     item:=listview1.Selected;
     if item=nil then exit;
     ix:=item.Index;
     if ix>=listview1.Items.Count-1 then exit;
      SendMessage(listview1.Handle,  WM_KEYDOWN,  VK_down,  0)
   end;
  if(key=VK_UP) then  //键盘上键
   begin
     item:=listview1.Selected;
     if item=nil then exit;
     ix:=item.Index;
     if ix<1 then exit;
     SendMessage(listview1.Handle,  WM_KEYDOWN,  VK_up,  0)
   end;
   listview1.ItemFocused :=listview1.Selected;
   item:=listview1.Selected ;
   edit1.Visible :=false;
   rect:=item.DisplayRect(drSelectBounds);
   edit1.SetBounds(edit1.left,rect.Top-1,edit1.Width,rect.Bottom-rect.Top+2);
   IF edtcol>0 then edit1.Text:=item.SubItems[edtcol-1]
               else edit1.Text:=item.Caption ;
   edit1.Visible:=true;
   edit1.SetFocus;

EXCEPT
END;
end;


//编辑控件内容改变后,保存改变到Listview1对应位置
procedure TForm1.Edit1Change(Sender: TObject);
begin
TRY
    if not edit1.Visible then exit;
    listview1.Selected.SubItems[edtcol-1]:=edit1.Text;
EXCEPT
END;
end;
//在LISTVIEW1上按下鼠标
procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
 rect:Trect;
 p:tpoint;
 wtmp,i:integer;
begin
TRY
  //显示编辑控件
  edit1.Visible:=false;
  //根据鼠标位置,得到所对应行的LISTITEM
  editem:=listview1.GetItemAt(x,y);
  if editem<>nil then
  begin
   //根据鼠标位置,计算出是哪个 Columns.
   p:=editem.Position;
   wtmp:=p.X;
   for i:=0 to listview1.Columns.Count-1 do
   if (x>wtmp) and (x<(wtmp+listview1.Column[i].Width))
     then  break  //找到对应的Columns,打断退出,I确定.
     else  inc(wtmp,listview1.Column[i].Width);
   //根据I的值,取得 Columns的对应位置。在对应位置按其它的SIZE放EDIT1。
   edtcol:=i;
   rect:=editem.DisplayRect(drSelectBounds);
   edit1.SetBounds(wtmp-1,rect.Top-1,listview1.Column[i].Width+1,rect.Bottom-rect.Top+2);
   if edtcol>0 then edit1.Text:=editem.SubItems[i-1]
               else edit1.Text:=editem.Caption;
   edit1.Visible:=true;
   edit1.SetFocus;
  end;
EXCEPT
END;
end;
//初始化,加入测试数据.
procedure TForm1.FormCreate(Sender: TObject);
var item:tlistitem;
    i:integer;
begin

 //将edit1的父亲选为LISTVIEW1,用以响应LISTVIEW1消息

 edit1.parent:=Listview1;

 //拦载LISTVIEW1鼠标消息

  FListViewWndProc1:=ListView1.WindowProc;
  ListView1.WindowProc := ListViewWndProc1;
 

  for  i:=0 to 10 do
   begin
      item:=listview1.Items.Add ;
      item.Caption :='123324';
      item.SubItems.Add('32r5aefs');
      item.SubItems.Add('SGASD');
      item.SubItems.Add('3445645');
   end;
end;

  上面的代码只是最基本的代码,仅可以通过键盘的上、下、左、右键控制EDIT在各个Column中切换,要将它做得更好,还要加入如拦截Column的宽度变化消息,以便Column变宽或变窄后相应的调整EDIT宽度等等。

相关文章推荐

Delphi在Listview中加入Eeit控件(转)

Delphi在Listview中加入Eeit控件 2010-07-15         作者:李海彬   阅读:821          Listview是一个非常有用的控件,我们常常...
  • icjava
  • icjava
  • 2012年02月06日 11:23
  • 7146

Delphi代码,listview控件

  • 2015年05月03日 01:40
  • 224KB
  • 下载

DELPHI高性能大容量SOCKET并发(二):IOCP完成端口控件封装

IOCP完成端口介绍: 完成端口模型是Windows平台下SOCKET端口模型最为复杂的一种I/O模型。如果一个应用程序需要同时管理为数众多的套接字,而且希望随着系统内安装的CPU数量的增多,应用程...

在delphi中引用第三方控件时,找不到dcu的解决办法

好久没有使用delphi7来编程了,由于以前的一个项目需要升级,今天又重拾delphi7。不得不说在当时delphi真的好强,可惜了borland,它曾经是我心中的英雄,编程的首选。闲话少说步入正题。...

VB ListView控件属性及用法

  • 2015年12月11日 12:36
  • 32KB
  • 下载

Android控件Spinner和ListView

  • 2016年01月07日 21:33
  • 78KB
  • 下载

Delphi xe5 控件TIdhttp的用法post,get解决中文乱码问题

网络接口如下图: 浏览器演示如下:http://112.64.158.30:7777/web/login!doLogin?data={"password":"yangtao123","userCo...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delphi在Listview中加入Eeit控件
举报原因:
原因补充:

(最多只允许输入30个字)